<!DOCTYPE html>
<!-- saved from url=(0053)http://www.whatwg.org/specs/web-workers/current-work/ -->
<HTML lang="en-US-x-hixie"><HEAD><META http-equiv="Content-Type" content="text/html; charset=UTF-8"><META charset="ascii"><TITLE>Web Workers</TITLE><LINK href="http://www.whatwg.org/style/specification" rel="stylesheet"><LINK href="http://www.whatwg.org/images/icon" rel="icon"></HEAD><BODY class="cfc">

  <HEADER class="head"><P><A class="logo" href="http://www.whatwg.org/" rel="home"><IMG alt="WHATWG" src="./Web Workers_files/logo"></A></P>
   <HGROUP><H1>Web Workers</H1>
    <H2 class="no-num no-toc">Draft Recommendation — 11 January 2010</H2>
   </HGROUP><P>You can take part in this work. <A href="http://www.whatwg.org/mailing-list">Join the working group's discussion list.</A></P>
   <P><STRONG>Web designers!</STRONG> We have a <A href="http://blog.whatwg.org/faq/">FAQ</A>, a <A href="http://forums.whatwg.org/">forum</A>, and a <A href="http://www.whatwg.org/mailing-list#help">help mailing list</A> for you!</P>
   <DL><DT>This version:</DT>
    <DD><A href="./Web Workers_files/Web Workers.htm">http://whatwg.org/ww</A></DD>
    <DT>Version history:</DT>
    <DD>Twitter messages (non-editorial changes only): <A href="http://twitter.com/WHATWG">http://twitter.com/WHATWG</A></DD>
    <DD>Commit-Watchers mailing list: <A href="http://lists.whatwg.org/listinfo.cgi/commit-watchers-whatwg.org">http://lists.whatwg.org/listinfo.cgi/commit-watchers-whatwg.org</A></DD>
    <DD>Interactive Web interface: <A href="http://html5.org/tools/web-workers-tracker">http://html5.org/tools/web-workers-tracker</A></DD>
    <DD>Subversion interface: <A href="http://svn.whatwg.org/webworkers/">http://svn.whatwg.org/webworkers/</A></DD>
    <DT>Issues:</DT>
    <DD>To send feedback: <A href="http://www.whatwg.org/mailing-list">whatwg@whatwg.org</A></DD>
    <DD>To view and vote on feedback: <A href="http://www.whatwg.org/issues/">http://www.whatwg.org/issues/</A></DD>
    <DT>Editor:</DT>
    <DD>Ian Hickson, Google, ian@hixie.ch</DD>
   </DL><P class="copyright">© Copyright 2004-2008 Apple Computer, Inc.,
   Mozilla Foundation, and Opera Software ASA.</P>
   <P class="copyright">You are granted a license to use, reproduce
   and create derivative works of this document.</P>
  </HEADER><HR><H2 class="no-num no-toc" id="abstract">Abstract</H2>

  <P>This specification defines an API that allows Web application
  authors to spawn background workers running scripts in parallel to
  their main page. This allows for thread-like operation with
  message-passing as the coordination mechanism.</P>


  <H2 class="no-num no-toc" id="status">Status of this document</H2>

  <P><STRONG>This is a work in progress!</STRONG> This document is
  changing on a daily if not hourly basis in response to comments and
  as a general part of its development process. Comments are very
  welcome, please send them to <A href="mailto:whatwg@whatwg.org">whatwg@whatwg.org</A>. Thank
  you.</P>

  <P>The current focus is in developing a first draft proposal.</P>

  <P>Implementors should be aware that this specification is not
  stable. <STRONG>Implementors who are not taking part in the
  discussions are likely to find the specification changing out from
  under them in incompatible ways.</STRONG> Vendors interested in
  implementing this specification before it eventually reaches the
  call for implementations should join the <A href="http://www.whatwg.org/mailing-list">WHATWG mailing list</A> and take part in the
  discussions.</P>

  <P>This specification is also being produced by the <A href="http://www.w3.org/2008/webapps/">W3C Web Apps WG</A>. The two
  specifications are identical from the table of contents onwards.</P>



  <H2 class="no-num no-toc" id="contents">Table of contents</H2>
  
<!--begin-toc-->
<OL class="toc">
 <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#introduction"><SPAN class="secno">1 </SPAN>Introduction</A>
  <OL>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#scope"><SPAN class="secno">1.1 </SPAN>Scope</A></LI>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#tutorial"><SPAN class="secno">1.2 </SPAN>Tutorial</A>
    <OL>
     <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#a-background-number-crunching-worker"><SPAN class="secno">1.2.1 </SPAN>A background number-crunching worker</A></LI>
     <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#a-worker-for-updating-a-client-side-database"><SPAN class="secno">1.2.2 </SPAN>A worker for updating a client-side database</A></LI>
     <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker-used-for-background-i/o"><SPAN class="secno">1.2.3 </SPAN>Worker used for background I/O</A></LI>
     <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#shared-workers"><SPAN class="secno">1.2.4 </SPAN>Shared workers</A></LI>
     <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#delegation"><SPAN class="secno">1.2.5 </SPAN>Delegation</A></LI>
     <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#providing-libraries"><SPAN class="secno">1.2.6 </SPAN>Providing libraries</A></LI></OL></LI></OL></LI>
 <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#conformance-requirements"><SPAN class="secno">2 </SPAN>Conformance requirements</A>
  <OL>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#dependencies"><SPAN class="secno">2.1 </SPAN>Dependencies</A></LI></OL></LI>
 <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#terminology"><SPAN class="secno">3 </SPAN>Terminology</A></LI>
 <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#infrastructure"><SPAN class="secno">4 </SPAN>Infrastructure</A>
  <OL>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#the-global-scope"><SPAN class="secno">4.1 </SPAN>The global scope</A>
    <OL>
     <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#the-workerglobalscope-abstract-interface"><SPAN class="secno">4.1.1 </SPAN>The <CODE>WorkerGlobalScope</CODE> abstract interface</A></LI>
     <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#dedicated-workers-and-the-dedicatedworkerglobalscope-interface"><SPAN class="secno">4.1.2 </SPAN>Dedicated workers and the <CODE>DedicatedWorkerGlobalScope</CODE> interface</A></LI>
     <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#shared-workers-and-the-sharedworkerglobalscope-inteface"><SPAN class="secno">4.1.3 </SPAN>Shared workers and the <CODE>SharedWorkerGlobalScope</CODE> inteface</A></LI></OL></LI>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#origins-of-workers"><SPAN class="secno">4.2 </SPAN>Origins of workers</A></LI>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#the-event-loop"><SPAN class="secno">4.3 </SPAN>The event loop</A></LI>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#the-worker's-lifetime"><SPAN class="secno">4.4 </SPAN>The worker's lifetime</A></LI>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#processing-model"><SPAN class="secno">4.5 </SPAN>Processing model</A></LI>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#runtime-script-errors"><SPAN class="secno">4.6 </SPAN>Runtime script errors</A></LI>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#creating-workers"><SPAN class="secno">4.7 </SPAN>Creating workers</A>
    <OL>
     <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#the-abstractworker-abstract-interface"><SPAN class="secno">4.7.1 </SPAN>The <CODE>AbstractWorker</CODE> abstract interface</A></LI>
     <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#dedicated-workers-and-the-worker-interface"><SPAN class="secno">4.7.2 </SPAN>Dedicated workers and the <CODE>Worker</CODE> interface</A></LI>
     <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#shared-workers-and-the-sharedworker-interface"><SPAN class="secno">4.7.3 </SPAN>Shared workers and the <CODE>SharedWorker</CODE> interface</A></LI></OL></LI></OL></LI>
 <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#apis-available-to-workers"><SPAN class="secno">5 </SPAN>APIs available to workers</A>
  <OL>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#importing-scripts-and-libraries"><SPAN class="secno">5.1 </SPAN>Importing scripts and libraries</A></LI>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#the-workernavigator-object"><SPAN class="secno">5.2 </SPAN>The <CODE>WorkerNavigator</CODE> object</A></LI>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#apis-defined-in-other-specifications"><SPAN class="secno">5.3 </SPAN>APIs defined in other specifications</A></LI>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#interface-objects-and-constructors"><SPAN class="secno">5.4 </SPAN>Interface objects and constructors</A></LI>
   <LI><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker-locations"><SPAN class="secno">5.5 </SPAN>Worker locations</A></LI></OL></LI>
 <LI><A class="no-num" href="http://www.whatwg.org/specs/web-workers/current-work/#references">References</A></LI>
 <LI><A class="no-num" href="http://www.whatwg.org/specs/web-workers/current-work/#acknowledgements">Acknowledgements</A></LI></OL>
<!--end-toc-->
  <HR><H2 id="introduction"><SPAN class="secno">1 </SPAN>Introduction</H2>

  <H3 id="scope"><SPAN class="secno">1.1 </SPAN>Scope</H3>

  <P><I>This section is non-normative.</I></P>

  <P>This specification defines an API for running scripts in the
  background independently of any user interface scripts.</P>

  <P>This allows for long-running scripts that are not interrupted by
  scripts that respond to clicks or other user interactions, and
  allows long tasks to be executed without yielding to keep the page
  responsive.</P>

  <P>Workers (as these background scripts are called herein) are
  relatively heavy-weight, and are not intended to be used in large
  numbers. For example, it would be inappropriate to launch one worker
  for each pixel of a four megapixel image. The examples below show
  some appropriate uses of workers.</P>

  <P>Generally, workers are expected to be long-lived, have a high
  start-up performance cost, and a high per-instance memory cost.</P>


  <H3 id="tutorial"><SPAN class="secno">1.2 </SPAN>Tutorial</H3>

  <P><I>This section is non-normative.</I></P>

  <P>There are a variety of uses that workers can be put to. The
  following subsections show various examples of this use.</P>

  <H4 id="a-background-number-crunching-worker"><SPAN class="secno">1.2.1 </SPAN>A background number-crunching worker</H4>

  <P><I>This section is non-normative.</I></P>

  <P>The simplest use of workers is for performing a computationally
  expensive task without interrupting the user interface.</P>

  <P>In this example, the main document spawns a worker to
  (naïvely) compute prime numbers, and progressively displays the
  most recently found prime number.</P>

  <P>The main page is as follows:</P>

  <PRE>&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
 &lt;head&gt;
  &lt;title&gt;Worker example: One-core computation&lt;/title&gt;
 &lt;/head&gt;
 &lt;body&gt;
  &lt;p&gt;The highest prime number discovered so far is: &lt;output id="result"&gt;&lt;/output&gt;&lt;/p&gt;
  &lt;script&gt;
   var worker = new Worker('worker.js');
   worker.onmessage = function (event) {
     document.getElementById('result').textContent = event.data;
   };
  &lt;/script&gt;
 &lt;/body&gt;
&lt;/html&gt;</PRE>

  <P>The <CODE title="dom-Worker"><A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-worker">Worker()</A></CODE> constructor call
  creates a worker and returns a <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker">Worker</A></CODE> object
  representing that worker, which is used to communicate with the
  worker. That object's <CODE title="handler-Worker-onmessage"><A href="http://www.whatwg.org/specs/web-workers/current-work/#handler-worker-onmessage">onmessage</A></CODE> event handler allows the code to receive messages from the worker.</P>

  <P>The worker itself is as follows:</P>

  <PRE>var n = 1;
search: while (true) {
  n += 1;
  for (var i = 2; i &lt;= Math.sqrt(n); i += 1)
    if (n % i == 0)
     continue search;
  // found a prime!
  postMessage(n);
}</PRE>

  <P>The bulk of this code is simply an unoptimized search for a prime
  number. To send a message back to the page, the <CODE title="dom-DedicatedWorkerGlobalScope-postMessage"><A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-dedicatedworkerglobalscope-postmessage">postMessage()</A></CODE>
  method is used to post a message when a prime is found.</P>

  <P><A href="http://www.whatwg.org/demos/workers/primes/page.html">View this example online</A>.</P>



  <H4 id="a-worker-for-updating-a-client-side-database"><SPAN class="secno">1.2.2 </SPAN>A worker for updating a client-side database</H4>

  <P><I>This section is non-normative.</I></P>

  <P>In this example, the main document spawns a worker whose only
  task is to listen for notifications from the server, and, when
  appropriate, either add or remove data from the client-side
  database.</P>

  <P>Since no communication occurs between the worker and the main
  page, the main page can start the worker by just doing:</P>

  <PRE>&lt;script&gt;
 new Worker('worker.js');
&lt;/script&gt;</PRE>

  <P>The worker itself is as follows:</P>

  <PRE>var server = new WebSocket('ws://whatwg.org/database');
var database = openDatabase('demobase', '1.0', 'Demo Database', 10240);
server.onmessage = function (event) {
  // data is in the format "command key value"
  var data = event.data.split(' ');
  switch (data[0]) {
    case '+':
     database.transaction(function(tx) {
       tx.executeSql('INSERT INTO pairs (key, value) VALUES (?, ?)', data[1], data[2]);
     });
    case '-':
     database.transaction(function(tx) {
       tx.executeSql('DELETE FROM pairs WHERE key=? AND value=?', data[1], data[2]);
     });
  }
};</PRE>

  <P>This connects to the server using the <CODE>WebSocket</CODE>
  mechanism and opens the local database (which, we presume, has been
  created earlier). The worker then just listens for messages from the
  server and acts on them as appropriate, forever (or until the main
  page is closed).</P>

  <P><A href="http://www.whatwg.org/demos/workers/database-updater/page.html">View
  this example online</A>. (This example will not actually function,
  since the server does not actually exist and the database is not
  created by this sample code.)</P>



  <H4 id="worker-used-for-background-i/o"><SPAN class="secno">1.2.3 </SPAN>Worker used for background I/O</H4>

  <P><I>This section is non-normative.</I></P>

  <P>In this example, the main document uses two workers, one for
  fetching stock updates for at regular intervals, and one for
  fetching performing search queries that the user requests.</P>

  <P>The main page is as follows:</P>

  <PRE>&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
 &lt;head&gt;
  &lt;title&gt;Worker example: Stock ticker&lt;/title&gt;
  &lt;script&gt;
   // TICKER
   var symbol = 'GOOG'; // default symbol to watch
   var ticker = new Worker('ticker.js');

   // SEARCHER
   var searcher = new Worker('searcher.js');
   function search(query) {
     searcher.postMessage(query);
   }

   // SYMBOL SELECTION UI
   function select(newSymbol) {
     symbol = newSymbol;
     ticker.postMessage(symbol);
   }
  &lt;/script&gt;
 &lt;/head&gt;
 &lt;body onload="search('')"&gt;
  &lt;p&gt;&lt;output id="symbol"&gt;&lt;/output&gt; &lt;output id="value"&gt;&lt;/output&gt;&lt;/p&gt;
  &lt;script&gt;
   ticker.onmessage = function (event) {
     var data = event.data.split(' ');
     document.getElementById('symbol').textContent = data[0];
     document.getElementById('value').textContent = data[1];
   };
   ticker.postMessage(symbol);
  &lt;/script&gt;
  &lt;p&gt;&lt;label&gt;Search: &lt;input type="text" autofocus oninput="search(this.value)"&gt;&lt;/label&gt;&lt;/p&gt;
  &lt;ul id="results"&gt;&lt;/ul&gt;
  &lt;script&gt;
   searcher.onmessage = function (event) {
     var data = event.data.split(' ');
     var results = document.getElementById('results');
     while (results.hasChildNodes()) // clear previous results
       results.removeChild(results.firstChild);
     for (var i = 0; i &lt; data.length; i += 1) {
       // add a list item with a button for each result
       var li = document.createElement('li');
       var button = document.createElement('button');
       button.value = data[i];
       button.type = 'button';
       button.onclick = function () { select(this.value); };
       button.textContent = data[i];
       li.appendChild(button);
       results.appendChild(li);
     }
   };
  &lt;/script&gt;
  &lt;p&gt;(The data in this example is not real. Try searching for "Google" or "Apple".)&lt;/p&gt;
 &lt;/body&gt;
&lt;/html&gt;</PRE>

  <P>The two workers use a common library for performing the actual
  network calls. This library is as follows:</P>

  <PRE>function get(url) {
  try {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, false);
    xhr.send();
    return xhr.responseText;
  } catch (e) {
    return ''; // turn all errors into empty results
  }
}</PRE>

  <P>The stock updater worker is as follows:</P>

  <PRE>importScripts('io.js');
var timer;
var symbol;
function update() {
  postMessage(symbol + ' ' + get('stock.cgi?' + symbol));
  timer = setTimeout(update, 10000);
}
onmessage = function (event) {
  if (timer)
    clearTimeout(timer);
  symbol = event.data;
  update();
};</PRE>

  <P>The search query worker is as follows:</P>

  <PRE>importScripts('io.js');
onmessage = function (event) {
  postMessage(get('search.cgi?' + event.data));
};</PRE>

  <P><A href="http://www.whatwg.org/demos/workers/stocks/page.html">View this example online</A>.</P>


  <H4 id="shared-workers"><SPAN class="secno">1.2.4 </SPAN>Shared workers</H4>

  <P><I>This section is non-normative.</I></P>

  <P>In this example, multiple windows (viewers) can be opened that
  are all viewing the same map. All the windows share the same map
  information, with a single worker coordinating all the viewers. Each
  viewer can move around independently, but if they set any data on
  the map, all the viewers are updated.</P>

  <P>The main page isn't interesting, it merely provides a way to open
  the viewers:</P>

  <PRE>&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
 &lt;head&gt;
  &lt;title&gt;Workers example: Multiviewer&lt;/title&gt;
  &lt;script&gt;
   function openViewer() {
     window.open('viewer.html');
   }
  &lt;/script&gt;
 &lt;/head&gt;
 &lt;body&gt;
  &lt;p&gt;&lt;button type=button onclick="openViewer()"&gt;Open a new
  viewer&lt;/button&gt;&lt;/p&gt;
  &lt;p&gt;Each viewer opens in a new window. You can have as many viewers
  as you like, they all view the same data.&lt;/p&gt;
 &lt;/body&gt;
&lt;/html&gt;</PRE>

  <P>The viewer is more involved:</P>

  <PRE>&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
 &lt;head&gt;
  &lt;title&gt;Workers example: Multiviewer viewer&lt;/title&gt;
  &lt;script&gt;
   var worker = new SharedWorker('worker.js', 'core');

   // CONFIGURATION
   function configure(event) {
     if (event.data.substr(0, 4) != 'cfg ') return;
     var name = event.data.substr(4).split(' ', 1);
     // update display to mention our name is name
     document.getElementsByTagName('h1')[0].textContent += ' ' + name;
     // no longer need this listener
     worker.port.removeEventListener('message', configure, false);
   }
   worker.port.addEventListener('message', configure, false);

   // MAP
   function paintMap(event) {
     if (event.data.substr(0, 4) != 'map ') return;
     var data = event.data.substr(4).split(',');
     // display tiles data[0] .. data[8]
     var canvas = document.getElementById('map');
     var context = canvas.getContext('2d');
     for (var y = 0; y &lt; 3; y += 1) {
       for (var x = 0; x &lt; 3; x += 1) {
         var tile = data[y * 3 + x];
         if (tile == '0')
           context.fillStyle = 'green';
         else 
           context.fillStyle = 'maroon';
         fillRect(x * 50, y * 50, 50, 50);
       }
     }
   }
   worker.port.addEventListener('message', paintMap, false);

   // PUBLIC CHAT
   function updatePublicChat(event) {
     if (event.data.substr(0, 4) != 'txt ') return;
     var name = event.data.substr(4).split(' ', 1);
     var message = event.data.substr(4 + length(name) + 1);
     // display "&lt;name&gt; message" in public chat
     var dialog = document.getElementById('public');
     var dt = document.createElement('dt');
     dt.textContent = name;
     dialog.appendChild(dt);
     var dd = document.createElement('dd');
     dd.textContent = message;
     dialog.appendChild(dd);
   }
   worker.port.addEventListener('message', updatePublicChat, false);

   // PRIVATE CHAT
   function startPrivateChat(event) {
     if (event.data.substr(0, 4) != 'msg ') return;
     var name = event.data.substr(4).split(' ', 1);
     var port = event.ports[0];
     // display a private chat UI
     var ul = document.getElementById('private');
     var li = document.createElement('li');
     var h3 = document.createElement('h3');
     h3.textContent = 'Private chat with ' + name;
     li.appendChild(h3);
     var dialog = document.createElement('dialog');
     var addMessage = function(name, message) {
       var dt = document.createElement('dt');
       dt.textContent = name;
       dialog.appendChild(dt);
       var dd = document.createElement('dd');
       dd.textContent = message;
       dialog.appendChild(dd);
     };
     port.onmessage = function (event) {
       addMessage(name, event.data);
     };
     li.appendChild(dialog);
     var form = document.createElement('form');
     var p = document.createElement('p');
     var input = document.createElement('input');
     input.size = 50;
     p.appendChild(input);
     p.appendChild(document.createTextNode(' '));
     var button = document.createElement('button');
     button.textContent = 'Post';
     p.appendChild(button);
     form.onsubmit = function () {
       port.postMessage(input.value);
       addMessage('me', input.value);
       input.value = '';
       return false;
     };
     form.appendChild(p);
     li.appendChild(form);
   }
   worker.port.addEventListener('message', startPrivateChat, false);

   worker.port.start();
  &lt;/script&gt;
 &lt;/head&gt;
 &lt;body&gt;
  &lt;h1&gt;Viewer&lt;/h1&gt;
  &lt;h2&gt;Map&lt;/h2&gt;
  &lt;p&gt;&lt;canvas id="map" height=150 width=150&gt;&lt;/canvas&gt;&lt;/p&gt;
  &lt;p&gt;
   &lt;button type=button onclick="worker.port.postMessage('mov left')"&gt;Left&lt;/button&gt;
   &lt;button type=button onclick="worker.port.postMessage('mov up')"&gt;Up&lt;/button&gt;
   &lt;button type=button onclick="worker.port.postMessage('mov down')"&gt;Down&lt;/button&gt;
   &lt;button type=button onclick="worker.port.postMessage('mov right')"&gt;Right&lt;/button&gt;
   &lt;button type=button onclick="worker.port.postMessage('set 0')"&gt;Set 0&lt;/button&gt;
   &lt;button type=button onclick="worker.port.postMessage('set 1')"&gt;Set 1&lt;/button&gt;
  &lt;/p&gt;
  &lt;h2&gt;Public Chat&lt;/h2&gt;
  &lt;dialog id="public"&gt;&lt;/dialog&gt;
  &lt;form onsubmit="worker.port.postMessage('txt ' + message.value); message.value = ''; return false;"&gt;
   &lt;p&gt;
    &lt;input type="text" name="message" size="50"&gt;
    &lt;button&gt;Post&lt;/button&gt;
   &lt;/p&gt;
  &lt;/form&gt;
  &lt;h2&gt;Private Chat&lt;/h2&gt;
  &lt;ul id="private"&gt;&lt;/ul&gt;
 &lt;/body&gt;
&lt;/html&gt;
</PRE>

  <P>There are several key things worth noting about the way the
  viewer is written.</P>

  <P><STRONG>Multiple listeners</STRONG>. Instead of a single message
  processing function, the code here attaches multiple event
  listeners, each one performing a quick check to see if it is
  relevant for the message. In this example it doesn't make much
  difference, but if multiple authors wanted to collaborate using a
  single port to communicate with a worker, it would allow for
  independent code instead of changes having to all be made to a
  single event handling function.</P>

  <P>Registering event listeners in this way also allows you to
  unregister specific listeners when you are done with them, as is
  done with the <CODE title="">configure()</CODE> method in this
  example.</P>

  <P>Finally, the worker:</P>

  <PRE>var nextName = 0;
function getNextName() {
  // this could use more friendly names
  // but for now just return a number
  return nextName++;
}

var map = [
 [0, 0, 0, 0, 0, 0, 0],
 [1, 1, 0, 1, 0, 1, 1],
 [0, 1, 0, 1, 0, 0, 0],
 [0, 1, 0, 1, 0, 1, 1],
 [0, 0, 0, 1, 0, 0, 0],
 [1, 0, 0, 1, 1, 1, 1],
 [1, 1, 0, 1, 1, 0, 1],
];

function wrapX(x) {
  if (x &lt; 0) return wrapX(x + map[0].length);
  if (x &gt;= map[0].length) return wrapX(x - map[0].length);
  return x;
}

function wrapY(y) {
  if (y &lt; 0) return wrapY(y + map.length);
  if (y &gt;= map[0].length) return wrapY(y - map.length);
  return y;
}

function sendMapData(callback) {
  var data = '';
  for (var y = viewer.y-1; y &lt;= viewer.y+1; y += 1) {
    for (var x = viewer.x-1; x &lt;= viewer.x+1; x += 1) {
      if (data != '')
        data += ',';
      data += map[y][x];
    }
  }
  callback('map ' + data);
}

var viewers = {};
onconnect = function (event) {
  event.ports[0]._name = getNextName();
  event.ports[0]._data = { port: event.port, x: 0, y: 0, };
  viewers[event.ports[0]._name] = event.port._data;
  event.ports[0].postMessage('cfg ' + name);
  event.ports[0].onmessage = getMessage;
  sendMapData(event.ports[0].postMessage);
};

function getMessage(event) {
  switch (event.data.substr(0, 4)) {
    case 'mov ':
      var direction = event.data.substr(4);
      var dx = 0;
      var dy = 0;
      switch (direction) {
        case 'up': dy = -1; break;
        case 'down': dy = 1; break;
        case 'left': dx = -1; break;
        case 'right': dx = 1; break;
      }
      event.target._data.x = wrapX(event.target._data.x + dx);
      event.target._data.y = wrapY(event.target._data.y + dy);
      sendMapData(event.target.postMessage);
      break;
    case 'set ':
      var value = event.data.substr(4);
      map[event.target._data.y][event.target._data.x] = value;
      for (var viewer in viewers)
        sendMapData(viewers[viewer].port.postMessage);
      break;
    case 'txt ':
      var name = event.target._name;
      var message = event.data.substr(4);
      for (var viewer in viewers)
        viewers[viewer].port.postMessage('txt ' + name + ' ' + message);
      break;
    case 'msg ':
      var party1 = event._data;
      var party2 = viewers[event.data.substr(4).split(' ', 1)];
      if (party2) {
        var channel = new MessageChannel();
        party1.port.postMessage('msg ' + party2.name, [channel.port1]);
        party2.port.postMessage('msg ' + party1.name, [channel.port2]);
      }
      break;
  }
}</PRE>

  <P><STRONG>Connecting to multiple pages</STRONG>. The script uses
  the <CODE title="handler-SharedWorkerGlobalScope-onconnect"><A href="http://www.whatwg.org/specs/web-workers/current-work/#handler-sharedworkerglobalscope-onconnect">onconnect</A></CODE>
  event listener to listen for multiple connections.</P>

  <P><STRONG>Direct channels</STRONG>. When the worker receives a
  "msg" message from one viewer naming another viewer, it sets up a
  direct connection between the two, so that the two viewers can
  communicate directly without the worker having to proxy all the
  messages.</P>

  <P><A href="http://www.whatwg.org/demos/workers/multiviewer/page.html">View this example online</A>.</P>


  <H4 id="delegation"><SPAN class="secno">1.2.5 </SPAN>Delegation</H4>

  <P><I>This section is non-normative.</I></P>

  <P>With multicore CPUs becoming prevalent, one way to obtain better
  performance is to split computationally expensive tasks amongst
  multiple workers. In this example, a computationally expensive task
  that is to be performed for every number from 1 to 10,000,000 is
  farmed out to ten subworkers.</P>

  <P>The main page is as follows, it just reports the result:</P>

  <PRE>&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
 &lt;head&gt;
  &lt;title&gt;Worker example: Multicore computation&lt;/title&gt;
 &lt;/head&gt;
 &lt;body&gt;
  &lt;p&gt;Result: &lt;output id="result"&gt;&lt;/output&gt;&lt;/p&gt;
  &lt;script&gt;
   var worker = new Worker('worker.js');
   worker.onmessage = function (event) {
     document.getElementById('result').textContent = event.data;
   };
  &lt;/script&gt;
 &lt;/body&gt;
&lt;/html&gt;</PRE>

  <P>The worker itself is as follows:</P>

  <PRE>// settings
var num_workers = 10;
var items_per_worker = 1000000;

// start the workers
var result = 0;
var pending_workers = num_workers;
for (var i = 0; i &lt; num_workers; i += 1) {
  var worker = new Worker('core.js');
  worker.postMessage(i * items_per_worker);
  worker.postMessage((i+1) * items_per_worker);
  worker.onmessage = storeResult;
}

// handle the results
function storeResult(event) {
  result += 1*event.data;
  pending_workers -= 1;
  if (pending_workers &lt;= 0)
    postMessage(result); // finished!
}</PRE>

  <P>It consists of a loop to start the subworkers, and then a handler
  that waits for all the subworkers to respond.</P>

  <P>The subworkers are implemented as follows:</P>

  <PRE>var start;
onmessage = getStart;
function getStart(event) {
  start = 1*event.data;
  onmessage = getEnd;
}

var end;
function getEnd(event) {
  end = 1*event.data;
  onmessage = null;
  work();
}

function work() {
  var result = 0;
  for (var i = start; i &lt; end; i += 1) {
    // perform some complex calculation here
    result += 1;
  }
  postMessage(result);
  close();
}</PRE>

  <P>They receive two numbers in two events, perform the computation
  for the range of numbers thus specified, and then report the result
  back to the parent.</P>

  <P><A href="http://www.whatwg.org/demos/workers/multicore/page.html">View this example online</A>.</P>


  <H4 id="providing-libraries"><SPAN class="secno">1.2.6 </SPAN>Providing libraries</H4>

  <P><I>This section is non-normative.</I></P>

  <P>Suppose that a cryptography library is made available that
  provides three tasks:</P>

  <DL><DT>Generate a public/private key pair</DT>

   <DD>Takes a port, on which it will send two messages, first the
   public key and then the private key.</DD>

   <DT>Given a plaintext and a public key, return the corresponding cyphertext</DT>

   <DD>Takes a port, to which any number of messages can be sent, the
   first giving the public key, and the remainder giving the
   plaintext, each of which is encrypted and then sent on that same
   channel as the cyphertext. The user can close the port when it is
   done encrypting content.</DD>

   <DT>Given a cyphertext and a private key, return the corresponding plaintext</DT>

   <DD>Takes a port, to which any number of messages can be sent, the
   first giving the private key, and the remainder giving the
   cyphertext, each of which is decrypted and then sent on that same
   channel as the plaintext. The user can close the port when it is
   done decrypting content.</DD>

  </DL><P>The library itself is as follows:</P>

  <PRE>function handleMessage(e) {
  if (e.data == "genkeys")
    genkeys(e.ports[0]);
  else if (e.data == "encrypt")
    encrypt(e.ports[0]);
  else if (e.data == "decrypt")
    decrypt(e.ports[0]);
}

function genkeys(p) {
  var keys = _generateKeyPair();
  p.postMessage(keys[0]);
  p.postMessage(keys[1]);
}

function encrypt(p) {
  var key, state = 0;
  p.onmessage = function (e) {
    if (state == 0) {
      key = e.data;
      state = 1;
    } else {
      p.postMessage(_encrypt(key, e.data));
    }
  };
}

function decrypt(p) {
  var key, state = 0;
  p.onmessage = function (e) {
    if (state == 0) {
      key = e.data;
      state = 1;
    } else {
      p.postMessage(_decrypt(key, e.data));
    }
  };
}

// support being used as a shared worker as well as a dedicated worker
if ('onmessage' in this) // dedicated worker
  onmessage = handleMessage;
else // shared worker
  onconnect = function (e) { e.port.onmessage = handleMessage; }


// the "crypto" functions:

function _generateKeyPair() {
  return [Math.random(), Math.random()];
}

function _encrypt(k, s) {
  return 'encrypted-' + k + ' ' + s;
}

function _decrypt(k, s) {
  return s.substr(s.indexOf(' ')+1);
}</PRE>

  <P>Note that the crypto functions here are just stubs and don't do
  real cryptography.</P>

  <P>This library could be used as follows:</P>

  <PRE>&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
 &lt;head&gt;
  &lt;title&gt;Worker example: Crypto library&lt;/title&gt;
  &lt;script&gt;
   var crytoLib = new Worker('libcrypto-v1.js'); // or could use 'libcrypto-v2.js'
   function getKeys() {
     var state = 0;
     cryptoLib.startConversation("genkeys").onmessage = function (e) {
       if (state == 0)
         document.getElementById('public').value = e.data;
       else if (state == 1)
         document.getElementById('private').value = e.data;
       state += 1;
     };
   }
   function enc() {
     var port = cryptoLib.startConversation("encrypt");
     port.postMessage(document.getElementById('public').value);
     port.postMessage(document.getElementById('input').value);
     port.onmessage = function (e) {
       document.getElementById('input').value = e.data;
       port.close();
     };
   }
   function dec() {
     var port = cryptoLib.startConversation("decrypt");
     port.postMessage(document.getElementById('private').value);
     port.postMessage(document.getElementById('input').value);
     port.onmessage = function (e) {
       document.getElementById('input').value = e.data;
       port.close();
     };
   }
  &lt;/script&gt;
  &lt;style&gt;
   textarea { display: block; }
  &lt;/style&gt;
 &lt;/head&gt;
 &lt;body onload="getKeys()"&gt;
  &lt;fieldset&gt;
   &lt;legend&gt;Keys&lt;/legend&gt;
   &lt;p&gt;&lt;label&gt;Public Key: &lt;textarea id="public"&gt;&lt;/textarea&gt;&lt;/label&gt;&lt;/p&gt;
   &lt;p&gt;&lt;label&gt;Private Key: &lt;textarea id="private"&gt;&lt;/textarea&gt;&lt;/label&gt;&lt;/p&gt;
  &lt;/fieldset&gt;
  &lt;p&gt;&lt;label&gt;Input: &lt;textarea id="input"&gt;&lt;/textarea&gt;&lt;/label&gt;&lt;/p&gt;
  &lt;p&gt;&lt;button onclick="enc()"&gt;Encrypt&lt;/button&gt; &lt;button onclick="dec()"&gt;Decrypt&lt;/button&gt;&lt;/p&gt;
 &lt;/body&gt;
&lt;/html&gt;</PRE>

  <P>A later version of the API, though, might want to offload all the
  crypto work onto subworkers. This could be done as follows:</P>

  <PRE>function handleMessage(e) {
  if (e.data == "genkeys")
    genkeys(e.ports[0]);
  else if (e.data == "encrypt")
    encrypt(e.ports[0]);
  else if (e.data == "decrypt")
    decrypt(e.ports[0]);
}

function genkeys(p) {
  var generator = new Worker('libcrypto-v2-generator.js');
  generator.postMessage('', [p]);
}

function encrypt(p) {
  p.onmessage = function (e) {
    var key = e.data;
    var encryptor = new Worker('libcrypto-v2-encryptor.js');
    encryptor.postMessage(key, [p]);
  };
}

function encrypt(p) {
  p.onmessage = function (e) {
    var key = e.data;
    var decryptor = new Worker('libcrypto-v2-decryptor.js');
    decryptor.postMessage(key, [p]);
  };
}

// support being used as a shared worker as well as a dedicated worker
if ('onmessage' in this) // dedicated worker
  onmessage = handleMessage;
else // shared worker
  onconnect = function (e) { e.ports[0].onmessage = handleMessage };
</PRE>

  <P>The little subworkers would then be as follows.</P>

  <P>For generating key pairs:</P>

  <PRE>onmessage = function (e) {
  var k = _generateKeyPair();
  e.ports[0].postMessage(k[0]);
  e.ports[0].postMessage(k[1]);
  close();
}

function _generateKeyPair() {
  return [Math.random(), Math.random()];
}</PRE>

  <P>For encrypting:</P>

  <PRE>onmessage = function (e) {
  var key = e.data;
  e.ports[0].onmessage = function (e) {
    var s = e.data;
    postMessage(_encrypt(key, s));
  }
}

function _encrypt(k, s) {
  return 'encrypted-' + k + ' ' + s;
}</PRE>

  <P>For decrypting:</P>

  <PRE>onmessage = function (e) {
  var key = e.data;
  e.ports[0].onmessage = function (e) {
    var s = e.data;
    postMessage(_decrypt(key, s));
  }
}

function _decrypt(k, s) {
  return s.substr(s.indexOf(' ')+1);
}</PRE>

  <P>Notice how the users of the API don't have to even know that this
  is happening — the API hasn't changed; the library can
  delegate to subworkers without changing its API, even though it is
  accepting data using message channels.</P>

  <P><A href="http://www.whatwg.org/demos/workers/crypto/page.html">View this example online</A>.</P>




  <H2 id="conformance-requirements"><SPAN class="secno">2 </SPAN>Conformance requirements</H2>

  <P>All diagrams, examples, and notes in this specification are
  non-normative, as are all sections explicitly marked non-normative.
  Everything else in this specification is normative.</P>

  <P>The key words "MUST", "MUST NOT", "REQUIRED", <!--"SHALL", "SHALL
  NOT",--> "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
  "OPTIONAL" in the normative parts of this document are to be
  interpreted as described in RFC2119. For readability, these words do
  not appear in all uppercase letters in this specification. <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsRFC2119">[RFC2119]</A></P>

  <P>Requirements phrased in the imperative as part of algorithms
  (such as "strip any leading space characters" or "return false and
  abort these steps") are to be interpreted with the meaning of the
  key word ("must", "should", "may", etc) used in introducing the
  algorithm.</P>

  <P>Some conformance requirements are phrased as requirements on
  attributes, methods or objects. Such requirements are to be
  interpreted as requirements on user agents.</P>

  <P>Conformance requirements phrased as algorithms or specific steps
  may be implemented in any manner, so long as the end result is
  equivalent. (In particular, the algorithms defined in this
  specification are intended to be easy to follow, and not intended to
  be performant.)</P>

  <P>The only conformance class defined by this specification is user
  agents.</P>

  <P>User agents may impose implementation-specific limits on
  otherwise unconstrained inputs, e.g. to prevent denial of service
  attacks, to guard against running out of memory, or to work around
  platform-specific limitations.</P>


  <H3 id="dependencies"><SPAN class="secno">2.1 </SPAN>Dependencies</H3>

  <P>This specification relies on several other underlying
  specifications.</P>

  <DL><DT>HTML5</DT>

   <DD>

    <P>Many fundamental concepts from HTML5 are used by this
    specification. <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsHTML5">[HTML5]</A></P>

   </DD>

   <DT>WebIDL</DT>

   <DD>

    <P>The IDL blocks in this specification use the semantics of the
    WebIDL specification. <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsWEBIDL">[WEBIDL]</A></P>

   </DD>

  </DL><H2 id="terminology"><SPAN class="secno">3 </SPAN>Terminology</H2>

  <P>The construction "a <CODE title="">Foo</CODE> object", where
  <CODE title="">Foo</CODE> is actually an interface, is sometimes
  used instead of the more accurate "an object implementing the
  interface <CODE title="">Foo</CODE>".</P>

  <P>The term DOM is used to refer to the API set made available to
  scripts in Web applications, and does not necessarily imply the
  existence of an actual <CODE>Document</CODE> object or of any other
  <CODE>Node</CODE> objects as defined in the DOM Core
  specifications. <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsDOMCORE">[DOMCORE]</A></P>

  <P>An IDL attribute is said to be <EM>getting</EM> when its value is
  being retrieved (e.g. by author script), and is said to be
  <EM>setting</EM> when a new value is assigned to it.</P>
  <P>The term "JavaScript" is used to refer to ECMA262, rather than
  the official term ECMAScript, since the term JavaScript is more
  widely known. <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsECMA262">[ECMA262]</A></P>

  <H2 id="infrastructure"><SPAN class="secno">4 </SPAN>Infrastructure</H2>

  <P>There are two kinds of workers; dedicated workers, and shared
  workers. Dedicated workers, once created, and are linked to their
  creator; but message ports can be used to communicate from a
  dedicated worker to multiple other browsing contexts or
  workers. Shared workers, on the other hand, are named, and once
  created any script running in the same <SPAN>origin</SPAN> can
  obtain a reference to that worker and communicate with it.</P>


  <H3 id="the-global-scope"><SPAN class="secno">4.1 </SPAN>The global scope</H3>

  <P>The global scope is the "inside" of a worker.</P>

  <H4 id="the-workerglobalscope-abstract-interface"><SPAN class="secno">4.1.1 </SPAN>The <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> abstract interface</H4>

  <PRE class="idl">interface <DFN id="workerglobalscope">WorkerGlobalScope</DFN> {
  readonly attribute <A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A> <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-self" title="dom-WorkerGlobalScope-self">self</A>;
  readonly attribute <A href="http://www.whatwg.org/specs/web-workers/current-work/#workerlocation">WorkerLocation</A> <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-location" title="dom-WorkerGlobalScope-location">location</A>;

  void <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-close" title="dom-WorkerGlobalScope-close">close</A>();
<!-- v2-onclose           attribute <span>Function</span> <span title="handler-WorkerGlobalScope-onclose">onclose</span>;
-->           attribute <SPAN>Function</SPAN> <A href="http://www.whatwg.org/specs/web-workers/current-work/#handler-workerglobalscope-onerror" title="handler-WorkerGlobalScope-onerror">onerror</A>;
};
<A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A> implements <A href="http://www.whatwg.org/specs/web-workers/current-work/#workerutils">WorkerUtils</A>;
<A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A> implements <SPAN>EventTarget</SPAN>;</PRE>

  <P>The <DFN id="dom-workerglobalscope-self" title="dom-WorkerGlobalScope-self"><CODE>self</CODE></DFN> attribute
  must return the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object itself.</P>

  <P>The <DFN id="dom-workerglobalscope-location" title="dom-WorkerGlobalScope-location"><CODE>location</CODE></DFN>
  attribute must return the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerlocation">WorkerLocation</A></CODE> object created
  for the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object when the worker was
  created. It represents the <SPAN>absolute URL</SPAN> of the script
  that was used to initialize the worker, after any redirects.</P>

  <HR><P>When a script invokes the <DFN id="dom-workerglobalscope-close" title="dom-WorkerGlobalScope-close"><CODE>close()</CODE></DFN>
  method on a <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object, the user agent
  must run the following steps (atomically):</P>

  <OL><LI><P>Discard any <SPAN title="concept-task">tasks</SPAN> that
   have been added to the <SPAN>event loop</SPAN>'s <SPAN title="task
   queue">task queues</SPAN>.</P>

<!-- v2-onclose
   <li><p><span>Queue a task</span> to <span>fire a simple
   event</span> named <code title="event-close">close</code> at the
   <code>WorkerGlobalScope</code> object.</p></li>
-->

   </LI><LI><P>Set the worker's <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object's
   <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</A> flag to
   true. (This prevents any further tasks from being queued.)</P></LI>

   <LI><P>Disentangle all the ports in the list of <A href="http://www.whatwg.org/specs/web-workers/current-work/#the-worker's-ports">the worker's
   ports</A>.</P></LI>

  </OL><P>The following are the <SPAN>event handlers</SPAN> (and their
  corresponding <SPAN title="event handler event type">event handler
  event types</SPAN>) that must be supported, as IDL attributes, by
  objects implementing the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE>
  interface:</P>

  <TABLE><THEAD><TR><TH><SPAN title="event handlers">Event handler</SPAN> </TH><TH><SPAN>Event handler event type</SPAN>
   </TH></TR></THEAD><TBODY><!-- v2-onclose    <tr><td><dfn title="handler-WorkerGlobalScope-onclose"><code>onclose</code></dfn> <td> <code title="event-close">close</code> --><TR><TD><DFN id="handler-workerglobalscope-onerror" title="handler-WorkerGlobalScope-onerror"><CODE>onerror</CODE></DFN> </TD><TD> <CODE title="event-error">error</CODE>
  </TD></TR></TBODY></TABLE><HR><P>The <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> interface must not exist if
  the interface's <SPAN>relevant namespace object</SPAN> is a
  <CODE>Window</CODE> object. <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsWEBIDL">[WEBIDL]</A></P>



  <H4 id="dedicated-workers-and-the-dedicatedworkerglobalscope-interface"><SPAN class="secno">4.1.2 </SPAN>Dedicated workers and the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</A></CODE> interface</H4>

  <PRE class="idl">[Supplemental, NoInterfaceObject]
interface <DFN id="dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</DFN> : <A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A> {
  void <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-dedicatedworkerglobalscope-postmessage" title="dom-DedicatedWorkerGlobalScope-postMessage">postMessage</A>(in any message, in optional <SPAN>MessagePortArray</SPAN> ports);<!--
  <span>MessagePort</span> <span title="dom-DedicatedWorkerGlobalScope-startConversation">startConversation</span>(in any message);-->
           attribute <SPAN>Function</SPAN> <A href="http://www.whatwg.org/specs/web-workers/current-work/#handler-dedicatedworkerglobalscope-onmessage" title="handler-DedicatedWorkerGlobalScope-onmessage">onmessage</A>;
};</PRE>

  <P><CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</A></CODE> objects act as if they
  had an implicit <CODE>MessagePort</CODE> associated with them. This
  port is part of a channel that is set up when the worker is created,
  but it is not exposed. This object must never be garbage collected
  before the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</A></CODE> object.</P>

  <P>All messages received by that port must immediately be retargeted
  at the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</A></CODE> object.</P>

  <P>The <DFN id="dom-dedicatedworkerglobalscope-postmessage" title="dom-DedicatedWorkerGlobalScope-postMessage"><CODE>postMessage()</CODE></DFN><!--
  and <dfn
  title="dom-DedicatedWorkerGlobalScope-startConversation"><code>startConversation()</code></dfn>-->
  method<!--s (startConversation)--> on
  <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</A></CODE> objects must act as if, when
  invoked, it<!--/they (startConversation)--> immediately invoked the
  method of the same name on the port, with the same arguments, and
  returned the same return value.</P>

  <P>The following are the <SPAN>event handlers</SPAN> (and their
  corresponding <SPAN title="event handler event type">event handler
  event types</SPAN>) that must be supported, as IDL attributes, by
  objects implementing the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</A></CODE>
  interface:</P>

  <TABLE><THEAD><TR><TH><SPAN title="event handlers">Event handler</SPAN> </TH><TH><SPAN>Event handler event type</SPAN>
   </TH></TR></THEAD><TBODY><TR><TD><DFN id="handler-dedicatedworkerglobalscope-onmessage" title="handler-DedicatedWorkerGlobalScope-onmessage"><CODE>onmessage</CODE></DFN> </TD><TD> <CODE title="event-message">message</CODE>
  </TD></TR></TBODY></TABLE><P>For the purposes of the <SPAN>application cache</SPAN> networking
  model, a dedicated worker is an extension of the <SPAN>cache
  host</SPAN> from which it was created.</P>



  <H4 id="shared-workers-and-the-sharedworkerglobalscope-inteface"><SPAN class="secno">4.1.3 </SPAN>Shared workers and the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworkerglobalscope">SharedWorkerGlobalScope</A></CODE> inteface</H4>

  <PRE class="idl">[Supplemental, NoInterfaceObject]
interface <DFN id="sharedworkerglobalscope">SharedWorkerGlobalScope</DFN> : <A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A> {
  readonly attribute DOMString <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-sharedworkerglobalscope-name" title="dom-SharedWorkerGlobalScope-name">name</A>;
  readonly attribute <SPAN>ApplicationCache</SPAN> <SPAN title="dom-SharedWorkerGlobalScope-applicationCache">applicationCache</SPAN>;
           attribute <SPAN>Function</SPAN> <A href="http://www.whatwg.org/specs/web-workers/current-work/#handler-sharedworkerglobalscope-onconnect" title="handler-SharedWorkerGlobalScope-onconnect">onconnect</A>;
};</PRE>

  <P>Shared workers receive message ports through <CODE title="event-WorkerGlobalScope-connect">connect</CODE> events on
  their global object for each connection.</P>

  <P>The <DFN id="dom-sharedworkerglobalscope-name" title="dom-SharedWorkerGlobalScope-name"><CODE>name</CODE></DFN>
  attribute must return the value it was assigned when the
  <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworkerglobalscope">SharedWorkerGlobalScope</A></CODE> object was created by the
  "<A href="http://www.whatwg.org/specs/web-workers/current-work/#run-a-worker">run a worker</A>" algorithm. Its value represents the name
  that can be used to obtain a reference to the worker using the
  <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworker">SharedWorker</A></CODE> constructor.</P>

  <P>The following are the <SPAN>event handlers</SPAN> (and their
  corresponding <SPAN title="event handler event type">event handler
  event types</SPAN>) that must be supported, as IDL attributes, by
  objects implementing the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworkerglobalscope">SharedWorkerGlobalScope</A></CODE>
  interface:</P>

  <TABLE><THEAD><TR><TH><SPAN title="event handlers">Event handler</SPAN> </TH><TH><SPAN>Event handler event type</SPAN>
   </TH></TR></THEAD><TBODY><TR><TD><DFN id="handler-sharedworkerglobalscope-onconnect" title="handler-SharedWorkerGlobalScope-onconnect"><CODE>onconnect</CODE></DFN> </TD><TD> <CODE title="event-connect">connect</CODE>
  </TD></TR></TBODY></TABLE><P>For the purposes of the <SPAN>application cache</SPAN> networking
  model, a shared worker is its own <SPAN>cache host</SPAN>. The
  <A href="http://www.whatwg.org/specs/web-workers/current-work/#run-a-worker">run a worker</A> algorithm takes care of associating the
  worker with an <SPAN>application cache</SPAN>.</P>

  <P class="note">The <CODE title="dom-SharedWorkerGlobalScope-applicationCache">applicationCache</CODE>
  attribute returns the <CODE>ApplicationCache</CODE> object for the
  worker.</P><!-- normative conf criteria is in the appcache section
  -->


  <H3 id="origins-of-workers"><SPAN class="secno">4.2 </SPAN>Origins of workers</H3>

  <P>Both the <SPAN>origin</SPAN> and <SPAN>effective script
  origin</SPAN> of scripts running in workers are the
  <SPAN>origin</SPAN> of the <SPAN>absolute URL</SPAN> given in that
  the worker's <CODE title="dom-WorkerGlobalScope-location"><A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-location">location</A></CODE> attribute
  represents.</P>



  <H3 id="the-event-loop"><SPAN class="secno">4.3 </SPAN>The event loop</H3>

  <P>Each <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object has an <SPAN>event
  loop</SPAN> distinct from those defined for <SPAN title="unit of
  related similar-origin browsing contexts">units of related
  similar-origin browsing contexts</SPAN>. This <SPAN>event
  loop</SPAN> has no associated <SPAN>browsing context</SPAN>, and its
  <SPAN title="task queue">task queues</SPAN> only have events,
  callbacks, and networking activity as <SPAN title="concept-task">tasks</SPAN>. The processing model of these
  <SPAN title="event loop">event loops</SPAN> is defined below in the
  <A href="http://www.whatwg.org/specs/web-workers/current-work/#run-a-worker">run a worker</A> algorithm.</P>

  <P>Each <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object also has a <DFN id="dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</DFN> flag, which must
  initially be false, but which can get set to true by the algorithms
  in the processing model section below.</P>

  <P>Once the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE>'s <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</A> flag is set to
  true, the <SPAN>event loop</SPAN>'s <SPAN title="task queue">task
  queues</SPAN> must discard any further <SPAN title="concept-task">tasks</SPAN> that would be added to them (tasks
  already on the queue are unaffected except where otherwise
  specified). Effectively, once the <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</A> flag is true,
  timers stop firing, notifications for all pending asynchronous
  operations are dropped, etc.</P>



  <H3 id="the-worker&#39;s-lifetime"><SPAN class="secno">4.4 </SPAN>The worker's lifetime</H3>

  <P>Workers communicate with other workers and with <SPAN title="browsing context">browsing contexts</SPAN> through <SPAN title="channel messaging">message channels</SPAN> and their
  <CODE>MessagePort</CODE> objects.</P>

  <P>Each <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> <VAR title="">worker global
  scope</VAR> has a list of <DFN id="the-worker&#39;s-ports">the worker's ports</DFN>, which
  consists of all the <CODE>MessagePort</CODE> objects that are
  entangled with another port and that have one (but only one) port
  owned by <VAR title="">worker global scope</VAR>. This list includes
  <!--all the <code>MessagePort</code> objects that are in events
  pending in the <span>event loop</span>, as well as (commented out
  because in practice it makes no difference either way as far as I
  can tell, and it would be hard to strictly implement since these
  ports might not yet be across the thread boundary)--> the implicit
  <CODE>MessagePort</CODE> in the case of <A href="http://www.whatwg.org/specs/web-workers/current-work/#dedicatedworkerglobalscope" title="DedicatedWorkerGlobalScope">dedicated workers</A>.</P>

  <P>Each <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> also has a list of <DFN id="the-worker&#39;s-workers">the
  worker's workers</DFN>. Initially this list is empty; it is
  populated when the worker creates or obtains further workers.</P>

  <P>Finally, each <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> also has a list of
  <DFN id="the-worker&#39;s-documents">the worker's <CODE>Document</CODE>s</DFN>. Initially this list
  is empty; it is populated when the worker is created.</P>

  <P>Whenever a <CODE>Document</CODE> <VAR title="">d</VAR> is <DFN id="add-a-document-to-the-worker&#39;s-documents" title="add a document to the worker&#39;s documents">added to the
  worker's <CODE>Document</CODE>s</DFN>, the user agent must, for each
  worker in the list of <A href="http://www.whatwg.org/specs/web-workers/current-work/#the-worker's-workers">the worker's workers</A> whose list
  of <A href="http://www.whatwg.org/specs/web-workers/current-work/#the-worker's-documents">the worker's <CODE>Document</CODE>s</A> does not contain
  <VAR title="">d</VAR>, <A href="http://www.whatwg.org/specs/web-workers/current-work/#add-a-document-to-the-worker's-documents" title="add a document to the worker&#39;s
  documents">add <VAR title="">d</VAR> to <VAR title="">q</VAR>'s
  <CODE>WorkerGlobalScope</CODE> owner's list of <SPAN>the worker's
  <CODE>Document</CODE>s</SPAN></A>.</P> <!-- suggestions welcome
  on making this sentence into understandable English -->

  <P>Whenever a <CODE>Document</CODE> object is <SPAN title="discard a
  Document">discarded</SPAN>, it must be removed from the list of
  <A href="http://www.whatwg.org/specs/web-workers/current-work/#the-worker's-documents">the worker's <CODE>Document</CODE>s</A> of each worker
  whose list contains that <CODE>Document</CODE>.</P>

  <P>Given a <SPAN>script's global object</SPAN> <VAR title="">o</VAR>
  when creating or obtaining a worker, the <DFN id="list-of-relevant-document-objects-to-add">list of relevant
  <CODE>Document</CODE> objects to add</DFN> depends on the type of
  <VAR title="">o</VAR>. If <VAR title="">o</VAR> is a
  <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object (i.e. if we are creating a
  nested worker), then the relevant <CODE>Document</CODE>s are the
  <CODE>Document</CODE>s that are in <VAR title="">o</VAR>'s own list
  of <A href="http://www.whatwg.org/specs/web-workers/current-work/#the-worker's-documents">the worker's <CODE>Document</CODE>s</A>. Otherwise, <VAR title="">o</VAR> is a <CODE>Window</CODE> object, and the relevant
  <CODE>Document</CODE> is just the <CODE>Document</CODE> that is the
  <SPAN>active document</SPAN> of the <CODE>Window</CODE> object <VAR title="">o</VAR>.</P>

  <HR><P>A worker is said to be a <DFN id="permissible-worker">permissible worker</DFN> if its
  list of <A href="http://www.whatwg.org/specs/web-workers/current-work/#the-worker's-documents">the worker's <CODE>Document</CODE>s</A> is not
  empty.</P>

  <P>A worker is said to be a <DFN id="protected-worker">protected worker</DFN> if it is a
  <A href="http://www.whatwg.org/specs/web-workers/current-work/#permissible-worker">permissible worker</A> and either it has outstanding
  timers, database transactions, or network connections, or its list
  of <A href="http://www.whatwg.org/specs/web-workers/current-work/#the-worker's-ports">the worker's ports</A> is not empty, or its
  <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> is actually a
  <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworkerglobalscope">SharedWorkerGlobalScope</A></CODE> object (i.e. the worker is a
  shared worker).</P>

  <P>A worker is said to be an <DFN id="active-needed-worker">active needed worker</DFN> if any
  of the <CODE>Document</CODE> objects in <A href="http://www.whatwg.org/specs/web-workers/current-work/#the-worker's-documents">the worker's
  <CODE>Document</CODE>s</A> are <SPAN>fully active</SPAN>.</P>

  <P>A worker is said to be a <DFN id="suspendable-worker">suspendable worker</DFN> if it is
  not an <A href="http://www.whatwg.org/specs/web-workers/current-work/#active-needed-worker">active needed worker</A> but it is a
  <A href="http://www.whatwg.org/specs/web-workers/current-work/#permissible-worker">permissible worker</A>.</P>


  <H3 id="processing-model"><SPAN class="secno">4.5 </SPAN>Processing model</H3>

  <P>When a user agent is to <DFN id="run-a-worker">run a worker</DFN> for a script with
  <SPAN>URL</SPAN> <VAR title="">url</VAR>, a browsing context <VAR title="">owner browsing context</VAR>, an origin <VAR title="">owner
  origin</VAR>, and with global scope <VAR title="">worker global
  scope</VAR>, it must run the following steps:</P>

  <OL><LI>

    <P>Create a completely separate and parallel execution environment
    (i.e. a separate thread or process or equivalent construct), and
    run the rest of these steps asynchronously in that context.</P>

   </LI>

   <LI><P>If <VAR title="">worker global scope</VAR> is actually a
   <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworkerglobalscope">SharedWorkerGlobalScope</A></CODE> object (i.e. the worker is a
   shared worker), and there are any <SPAN title="relevant application
   cache">relevant application caches</SPAN> that are identified by a
   manifest URL with the <SPAN>same origin</SPAN> as <VAR title="">url</VAR> and that have <VAR title="">url</VAR> as one of
   their entries, <EM>not</EM> excluding entries marked as <SPAN title="concept-appcache-foreign">foreign</SPAN>, then associate the
   <VAR title="">worker global scope</VAR> with the <SPAN title="concept-appcache-selection">most appropriate application
   cache</SPAN> of those that match.</P></LI>

   <LI>

    <P>Attempt to <SPAN>fetch</SPAN> the resource identified by <VAR title="">url</VAR>, from the <VAR title="">owner origin</VAR>.</P>
    <!-- not http-origin privacy sensitive -->

    <P>If the attempt fails, or if the attempt involves any redirects
    to URIs that do not have the <SPAN>same origin</SPAN> as <VAR title="">url</VAR> (even if the final URI is at the <SPAN>same
    origin</SPAN> as the original <VAR title="">url</VAR>), then for
    each <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker">Worker</A></CODE> or <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworker">SharedWorker</A></CODE> object
    associated with <VAR title="">worker global scope</VAR>,
    <SPAN>queue a task</SPAN> to <SPAN>fire a simple event</SPAN>
    named <CODE title="event-error">error</CODE> at that
    object. Abort these steps.</P>

    <P>If the attempt succeeds, then convert the script resource to
    Unicode by assuming it was encoded as UTF-8, to obtain its <VAR title="">source</VAR>.</P>

    <P>Let <VAR title="">language</VAR> be JavaScript.</P>

    <P class="note">As with <CODE>script</CODE> elements, the MIME
    type of the script is ignored. Unlike with <CODE>script</CODE>
    elements, there is no way to override the type. It's always
    assumed to be JavaScript.</P>

   </LI>

   <LI>

    <P>A new <SPAN title="concept-script">script</SPAN> is now
    created, as follows.</P>

    <P>Create a new <SPAN>script execution environment</SPAN>
    set up as appropriate for the scripting language <VAR title="">language</VAR>.</P>

    <P>Parse/compile/initialize <VAR title="">source</VAR> using that
    <SPAN>script execution environment</SPAN>, as appropriate for <VAR title="">language</VAR>, and thus obtain a <SPAN>list of code
    entry-points</SPAN>; set the <I>initial code entry-point</I> to
    the entry-point for any executable code to be immediately run.</P>

    <P>Set the <SPAN>script's global object</SPAN> to <VAR title="">worker global scope</VAR>.</P>

    <P>Set the <SPAN>script's browsing context</SPAN> to <VAR title="">owner browsing context</VAR>.</P>

    <P>Set the <SPAN>script's URL character encoding</SPAN> to
    UTF-8. (This is just used for encoding non-ASCII characters in the
    query component of URLs.)</P>

    <P>Set the <SPAN>script's base URL</SPAN> to <VAR title="">url</VAR>.</P>

   </LI>

   <LI>

    <P><STRONG>Closing orphan workers</STRONG>: Start monitoring the
    worker such that no sooner than it stops being either a
    <A href="http://www.whatwg.org/specs/web-workers/current-work/#protected-worker">protected worker</A> or a <A href="http://www.whatwg.org/specs/web-workers/current-work/#suspendable-worker">suspendable
    worker</A>, and no later than it stops being a
    <A href="http://www.whatwg.org/specs/web-workers/current-work/#permissible-worker">permissible worker</A>, <VAR title="">worker global
    scope</VAR>'s <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</A> flag is set
    to true<!-- v2-onclose and <span title="queue a task">a task is
    queued</span> to <span>fire a simple event</span> named <code
    title="event-close">close</code> at <var title="">worker global
    scope</var>-->.</P>

   </LI>

   <LI>

    <P><STRONG>Suspending workers</STRONG>: Start monitoring the
    worker, such that whenever <VAR title="">worker global
    scope</VAR>'s <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</A> flag is false
    and the worker is a <A href="http://www.whatwg.org/specs/web-workers/current-work/#suspendable-worker">suspendable worker</A>, the user
    agent suspends execution of script in that worker until such time
    as either the <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</A> flag switches
    to true or the worker stops being a <A href="http://www.whatwg.org/specs/web-workers/current-work/#suspendable-worker">suspendable
    worker</A>.</P>

   </LI>

   <LI>

    <P><SPAN title="jump to a code entry-point">Jump</SPAN> to the
    <SPAN title="concept-script">script</SPAN>'s <I>initial code
    entry-point</I>, and let that run until it either returns, fails
    to catch an exception, or gets prematurely aborted by the
    "<A href="http://www.whatwg.org/specs/web-workers/current-work/#kill-a-worker">kill a worker</A>" or "<A href="http://www.whatwg.org/specs/web-workers/current-work/#terminate-a-worker">terminate a worker</A>"
    algorithms defined below.</P>

<!-- v2-onclose
    <p class="note">If the script gets aborted by the "<span>kill a
    worker</span>" algorithm, then that same algorithm will cause
    there to only be a single <span title="concept-task">task</span>
    in the <span>event loop</span> at the next step, namely the task
    for the <code title="message-close">close</code> event. The
    "<span>terminate a worker</span>" algorithm removes all the
    events.</p>
-->

   </LI>

   <LI><P>If <VAR title="">worker global scope</VAR> is actually a
   <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</A></CODE> object (i.e. the worker is
   a dedicated worker), then enable the <SPAN>port message
   queue</SPAN> of the worker's implicit port.</P></LI>

   <LI>

    <P><I title="">Event loop</I>: Wait until either there is a <SPAN title="concept-task">task</SPAN> in one of the <SPAN>event
    loop</SPAN>'s <SPAN title="task queue">task queues</SPAN> or <VAR title="">worker global scope</VAR>'s <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</A> flag is set
    to true.</P>

   </LI>

   <LI>

    <P>Run the oldest task on one of the <SPAN>event loop</SPAN>'s
    <SPAN title="task queue">task queues</SPAN>, if any. The user
    agent may pick any <SPAN>task queue</SPAN>.</P>

    <P class="note">The handling of events or the execution of
    callbacks might get prematurely aborted by the "<A href="http://www.whatwg.org/specs/web-workers/current-work/#kill-a-worker">kill a
    worker</A>" or "<A href="http://www.whatwg.org/specs/web-workers/current-work/#terminate-a-worker">terminate a worker</A>" algorithms
    defined below.</P>

   </LI>

   <LI>

    <P>Remove the task run in the previous step, if any, from its
    <SPAN>task queue</SPAN>.</P>

   </LI>

   <LI>

    <P>If there are any more events in the <SPAN>event loop</SPAN>'s
    <SPAN title="task queue">task queues</SPAN> or if <VAR title="">worker global scope</VAR>'s <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</A> flag is set
    to false, then jump back to the step above labeled <I>event
    loop</I>.</P>

   </LI>

   <LI>

    <P>If there are any outstanding transactions that have callbacks
    that involve <SPAN title="concept-script">scripts</SPAN> whose
    <SPAN title="script&#39;s global object">global object</SPAN> is the
    <VAR title="">worker global scope</VAR>, roll them back (without
    invoking any of the callbacks).</P>

   </LI>

   <LI>

    <P>Empty the <VAR title="">worker global scope</VAR>'s <SPAN>list
    of active timeouts</SPAN> and its <SPAN>list of active
    intervals</SPAN>.</P>

   </LI>

<!-- v2-onclose
   <li>

    <p>For each <code>Worker</code> or <code>SharedWorker</code>
    object associated with <var title="">worker global scope</var>,
    <span>queue a task</span> to <span>fire a simple event</span>
    named <code title="event-close">close</code> at that object.</p>

   </li>
-->
  </OL><HR><P>When a user agent is to <DFN id="kill-a-worker">kill a worker</DFN> it must
  run the following steps in parallel with the worker's main loop (the
  "<A href="http://www.whatwg.org/specs/web-workers/current-work/#run-a-worker">run a worker</A>" processing model defined above):</P>

  <OL><!-- v2-onclose
   <li><p>If the worker's <code>WorkerGlobalScope</code> object's
   <span title="dom-WorkerGlobalScope-closing">closing</span> flag is
   false, <span>queue a task</span> to <span>fire a simple
   event</span> named <code title="event-close">close</code> at the
   worker's <code>WorkerGlobalScope</code> object.</p></li>
--><LI><P>Set the worker's <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object's <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</A> flag to
   true.</P></LI>

<!-- v2-onclose
   <li><p>Wait a user-agent-defined amount of time. If the "<span>run
   a worker</span>" processing model defined above immediately starts
   running event listeners registered for the <code
   title="event-close">close</code> event, this time should not be
   zero &mdash; the idea is that the <code
   title="event-close">close</code> event can be used to clean up
   when shutting down unexpectedly.</p></li>
-->

   <LI><P>If there are any <SPAN title="concept-task">tasks</SPAN>
   queued in the <SPAN>event loop</SPAN>'s <SPAN title="task
   queue">task queues</SPAN><!-- v2-onclose other than the <code
   title="event-close">close</code> event that this algorithm just
   added-->, discard them without processing them.</P></LI>

<!-- v2-onclose
   <li><p>If the <code title="event-close">close</code> event that
   this algorithm just queued hasn't yet been dispatched, then abort
   the script currently running in the worker.</p></li>
-->

   <LI><P>Wait a user-agent-defined amount of time.</P></LI>

   <LI><P>Abort the script currently running in the worker<!--
   v2-onclose (if any script is running, then it will be a handler for
   the <code title="event-close">close</code> event)-->.</P></LI>

  </OL><P>User agents may invoke the "<A href="http://www.whatwg.org/specs/web-workers/current-work/#kill-a-worker">kill a worker</A>"
  processing model on a worker at any time, e.g. in response to user
  requests, in response to CPU quota management, or when a worker
  stops being an <A href="http://www.whatwg.org/specs/web-workers/current-work/#active-needed-worker">active needed worker</A> if the worker
  continues executing even after its <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</A> flag was
  set to true.</P>

  <HR><P>When a user agent is to <DFN id="terminate-a-worker">terminate a worker</DFN> it must run
  the following steps in parallel with the worker's main loop (the
  "<A href="http://www.whatwg.org/specs/web-workers/current-work/#run-a-worker">run a worker</A>" processing model defined above):</P>

  <OL><LI><P>Set the worker's <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object's
   <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</A> flag to
   true.</P></LI>

   <LI><P>If there are any <SPAN title="concept-task">tasks</SPAN>
   queued in the <SPAN>event loop</SPAN>'s <SPAN title="task
   queue">task queues</SPAN>, discard them without processing
   them.</P></LI>

   <LI><P>Abort the script currently running in the worker.</P></LI>

   <LI><P>If the worker's <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object is
   actually a <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</A></CODE> object (i.e. the
   worker is a dedicated worker), then empty the <SPAN>port message
   queue</SPAN> of the port that the worker's implicit port is
   entangled with.</P></LI>

  </OL><HR><P>The <SPAN>task source</SPAN> for the tasks mentioned above is the
  <SPAN>DOM manipulation task source</SPAN>.</P>


  <H3 id="runtime-script-errors"><SPAN class="secno">4.6 </SPAN>Runtime script errors</H3>

  <P>Whenever an uncaught runtime script error occurs in one of the
  worker's scripts, if the error did not occur while handling a
  previous script error, the user agent must <SPAN>report the
  error</SPAN> using the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object's <CODE title="handler-WorkerGlobalScope-onerror"><A href="http://www.whatwg.org/specs/web-workers/current-work/#handler-workerglobalscope-onerror">onerror</A></CODE>
  attribute.
  
  <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsHTML5">[HTML5]</A>
  
  </P>

  <P>For shared workers, if the error is still <I title="concept-error-nothandled">not handled</I> afterwards, or if
  the error occurred while handling a previous script error, the error
  may be reported to the user.
  
  <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsHTML5">[HTML5]</A>
  
  </P>

  <P>For dedicated workers, if the error is still <I title="concept-error-nothandled">not handled</I> afterwards, or if
  the error occurred while handling a previous script error, the user
  agent must <SPAN>queue a task</SPAN> to <A href="http://www.whatwg.org/specs/web-workers/current-work/#fire-a-worker-error-event">fire a worker error
  event</A> at the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker">Worker</A></CODE> object associated with the
  worker.</P>

  <P>When the user agent is to <DFN id="fire-a-worker-error-event">fire a worker error event</DFN> at
  a <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker">Worker</A></CODE> object, it must dispatch an event that uses
  the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#errorevent">ErrorEvent</A></CODE> interface, with the name <CODE title="event-error">error</CODE>, that doesn't bubble and is
  cancelable, with its <CODE title="dom-ErrorEvent-message"><A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-errorevent-message">message</A></CODE>, <CODE title="dom-ErrorEvent-filename"><A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-errorevent-filename">filename</A></CODE>, and <CODE title="dom-ErrorEvent-lineno"><A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-errorevent-lineno">lineno</A></CODE> attributes set
  appropriately. The default action of this event depends on whether
  the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker">Worker</A></CODE> object is itself in a worker. If it is, and
  that worker is also a dedicated worker, then the user agent must
  again <SPAN>queue a task</SPAN> to <A href="http://www.whatwg.org/specs/web-workers/current-work/#fire-a-worker-error-event">fire a worker error
  event</A> at the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker">Worker</A></CODE> object associated with
  <EM>that</EM> worker. Otherwise, then the error may be reported
  to the user.</P>

  <P>The <SPAN>task source</SPAN> for the tasks mentioned above is the
  <SPAN>DOM manipulation task source</SPAN>.</P>

  <HR><PRE class="idl">interface <DFN id="errorevent">ErrorEvent</DFN> : Event {
  readonly attribute DOMString <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-errorevent-message" title="dom-ErrorEvent-message">message</A>;
  readonly attribute DOMString <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-errorevent-filename" title="dom-ErrorEvent-filename">filename</A>;
  readonly attribute unsigned long <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-errorevent-lineno" title="dom-ErrorEvent-lineno">lineno</A>;
  void <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-errorevent-initerrorevent" title="dom-ErrorEvent-initErrorEvent">initErrorEvent</A>(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString messageArg, in DOMString filenameArg, in unsigned long linenoArg);
};</PRE>

  <P>The <DFN id="dom-errorevent-initerrorevent" title="dom-ErrorEvent-initErrorEvent"><CODE>initErrorEvent()</CODE></DFN>
  method must initialize the event in a manner analogous to the
  similarly-named method in the DOM Events interfaces. <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsDOMEVENTS">[DOMEVENTS]</A></P>

  <P>The <DFN id="dom-errorevent-message" title="dom-ErrorEvent-message"><CODE>message</CODE></DFN>
  attribute represents the error message.</P>

  <P>The <DFN id="dom-errorevent-filename" title="dom-ErrorEvent-filename"><CODE>filename</CODE></DFN>
  attribute represents the <SPAN>absolute URL</SPAN> of the script in
  which the error originally occurred.</P>

  <P>The <DFN id="dom-errorevent-lineno" title="dom-ErrorEvent-lineno"><CODE>lineno</CODE></DFN>
  attribute represents the line number where the error occurred in the
  script.</P>



  <H3 id="creating-workers"><SPAN class="secno">4.7 </SPAN>Creating workers</H3>

  <H4 id="the-abstractworker-abstract-interface"><SPAN class="secno">4.7.1 </SPAN>The <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#abstractworker">AbstractWorker</A></CODE> abstract interface</H4>

  <PRE class="idl">[Supplemental, NoInterfaceObject]
interface <DFN id="abstractworker">AbstractWorker</DFN> {
           attribute <SPAN>Function</SPAN> <A href="http://www.whatwg.org/specs/web-workers/current-work/#handler-abstractworker-onerror" title="handler-AbstractWorker-onerror">onerror</A>;
<!-- v2-onclose           attribute <span>Function</span> <span title="handler-AbstractWorker-onclose">onclose</span>; -->
};
<A href="http://www.whatwg.org/specs/web-workers/current-work/#abstractworker">AbstractWorker</A> implements <SPAN>EventTarget</SPAN>;</PRE>

  <P>The following are the <SPAN>event handlers</SPAN> (and their
  corresponding <SPAN title="event handler event type">event handler
  event types</SPAN>) that must be supported, as IDL attributes, by
  objects implementing the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#abstractworker">AbstractWorker</A></CODE> interface:</P>

  <TABLE><THEAD><TR><TH><SPAN title="event handlers">Event handler</SPAN> </TH><TH><SPAN>Event handler event type</SPAN>
   </TH></TR></THEAD><TBODY><TR><TD><DFN id="handler-abstractworker-onerror" title="handler-AbstractWorker-onerror"><CODE>onerror</CODE></DFN> </TD><TD> <CODE title="event-error">error</CODE>
<!-- v2-onclose    <tr><td><dfn title="handler-AbstractWorker-onclose"><code>onclose</code></dfn> <td> <code title="event-close">close</code> -->
  </TD></TR></TBODY></TABLE><H4 id="dedicated-workers-and-the-worker-interface"><SPAN class="secno">4.7.2 </SPAN>Dedicated workers and the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker">Worker</A></CODE> interface</H4>

  <PRE class="idl">[<A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-worker" title="dom-Worker">Constructor</A>(in DOMString scriptURL)]
interface <DFN id="worker">Worker</DFN> : <A href="http://www.whatwg.org/specs/web-workers/current-work/#abstractworker">AbstractWorker</A> {
  void <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-worker-terminate" title="dom-Worker-terminate">terminate</A>();

  void <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-worker-postmessage" title="dom-Worker-postMessage">postMessage</A>(in any message, in optional <SPAN>MessagePortArray</SPAN> ports);<!--
  <span>MessagePort</span> <span title="dom-Worker-startConversation">startConversation</span>(in any message);-->
           attribute <SPAN>Function</SPAN> <A href="http://www.whatwg.org/specs/web-workers/current-work/#handler-worker-onmessage" title="handler-Worker-onmessage">onmessage</A>;
};</PRE>

  <P>The <DFN id="dom-worker-terminate" title="dom-Worker-terminate"><CODE>terminate()</CODE></DFN> method,
  when invoked, must cause the "<A href="http://www.whatwg.org/specs/web-workers/current-work/#terminate-a-worker">terminate a worker</A>"
  algorithm to be run on the worker with with the object is
  associated.</P>

  <P><CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker">Worker</A></CODE> objects act as if they had an implicit
  <CODE>MessagePort</CODE> associated with them. This port is part of
  a channel that is set up when the worker is created, but it is not
  exposed. This object must never be garbage collected before the
  <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker">Worker</A></CODE> object.</P>

  <P>All messages received by that port must immediately be retargeted
  at the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker">Worker</A></CODE> object.</P>

  <P>The <DFN id="dom-worker-postmessage" title="dom-Worker-postMessage"><CODE>postMessage()</CODE></DFN><!--
  and <dfn
  title="dom-Worker-startConversation"><code>startConversation()</code></dfn>-->
  method<!--s (startConversation)--> on <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker">Worker</A></CODE> objects
  must act as if, when invoked, it<!--/they (startConversation)-->
  immediately invoked the method of the same name on the port, with
  the same arguments, and returned the same return value.</P>

  <P>The following are the <SPAN>event handlers</SPAN> (and their
  corresponding <SPAN title="event handler event type">event handler
  event types</SPAN>) that must be supported, as IDL attributes, by
  objects implementing the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker">Worker</A></CODE> interface:</P>

  <TABLE><THEAD><TR><TH><SPAN title="event handlers">Event handler</SPAN> </TH><TH><SPAN>Event handler event type</SPAN>
   </TH></TR></THEAD><TBODY><TR><TD><DFN id="handler-worker-onmessage" title="handler-Worker-onmessage"><CODE>onmessage</CODE></DFN> </TD><TD> <CODE title="event-message">message</CODE>
  </TD></TR></TBODY></TABLE><HR><P>When the <DFN id="dom-worker" title="dom-Worker"><CODE>Worker(<VAR title="">scriptURL</VAR>)</CODE></DFN> constructor is invoked, the
  user agent must run the following steps:</P>

  <OL><LI><P><SPAN title="resolve a url">Resolve</SPAN> the <VAR title="">scriptURL</VAR> argument relative to the <SPAN>entry
   script</SPAN>'s <SPAN title="script&#39;s base URL">base URL</SPAN>,
   when the method is invoked.</P></LI>

   <LI><P>If this fails, throw a <CODE>SYNTAX_ERR</CODE>
   exception.</P></LI>

   <LI>

    <P>If the <SPAN>origin</SPAN> of the resulting <SPAN>absolute
    URL</SPAN> is not the <SPAN title="same origin">same</SPAN> as the
    origin of the <SPAN>entry script</SPAN>, then throw a
    <CODE>SECURITY_ERR</CODE> exception.</P>

    <P class="note">Thus, scripts must be external files with the same
    scheme as the original page: you can't load a script from a <CODE title="">data:</CODE> URL or <CODE title="">javascript:</CODE>
    URL, and a <CODE>https:</CODE> page couldn't start workers using
    scripts with <CODE>http:</CODE> URLs.</P>

   </LI>

   <LI><P>Create a new <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</A></CODE>
   object. Let <VAR title="">worker global scope</VAR> be this new
   object.</P></LI>

   <LI><P>Create a new <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#worker">Worker</A></CODE> object, associated with
   <VAR title="">worker global scope</VAR>. Let <VAR title="">worker</VAR> be this new object.</P></LI>

   <LI><P><SPAN>Create a new <CODE>MessagePort</CODE> object</SPAN>
   owned by the <SPAN title="script&#39;s global object">global
   object</SPAN> of the <SPAN title="concept-script">script</SPAN> that
   invoked the constructor. Let this be the <VAR title="">outside
   port</VAR>.</P></LI>

   <LI><P>Associate the <VAR title="">outside port</VAR> with <VAR title="">worker</VAR>.</P></LI>

   <LI><P><SPAN>Create a new <CODE>MessagePort</CODE> object</SPAN>
   owned by <VAR title="">worker global scope</VAR>. Let <VAR title="">inside port</VAR> be this new object.</P></LI>

   <LI><P>Associate <VAR title="">inside port</VAR> with <VAR title="">worker global scope</VAR>.</P></LI>

   <LI><P><SPAN>Entangle</SPAN> <VAR title="">outside port</VAR> and
   <VAR title="">inside port</VAR>.</P></LI>

   <LI><P>Return <VAR title="">worker</VAR>, and run the following
   steps asynchronously.</P></LI>

<!-- (this is done by the "run a worker" algorithm)
   <li><p>Enable <var title="">inside port</var>'s <span>port message
   queue</span>.</p></li>
-->

   <LI><P>Enable <VAR title="">outside port</VAR>'s <SPAN>port message
   queue</SPAN>.</P></LI>

   <LI>

    <P>Let <VAR title="">docs</VAR> be the <A href="http://www.whatwg.org/specs/web-workers/current-work/#list-of-relevant-document-objects-to-add">list of relevant
    <CODE>Document</CODE> objects to add</A> given the <SPAN title="script&#39;s global object">global object</SPAN> of the <SPAN title="concept-script">script</SPAN> that invoked the
    constructor.</P>

   </LI>

   <LI>

    <P><A href="http://www.whatwg.org/specs/web-workers/current-work/#add-a-document-to-the-worker's-documents" title="add a document to the worker&#39;s documents">Add to
    <VAR title="">worker global scope</VAR>'s list of <SPAN>the
    worker's <CODE>Document</CODE>s</SPAN></A> the
    <CODE>Document</CODE> objects in <VAR title="">docs</VAR>.</P>

   </LI>

   <LI>

    <P>If the <SPAN title="script&#39;s global object">global object</SPAN>
    of the <SPAN title="concept-script">script</SPAN> that invoked the
    constructor is a <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object (i.e. we
    are creating a nested worker), add <VAR title="">worker global
    scope</VAR> to the list of <A href="http://www.whatwg.org/specs/web-workers/current-work/#the-worker's-workers">the worker's workers</A> of the
    <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object that is the <SPAN title="script&#39;s global object">global object</SPAN> of the <SPAN title="concept-script">script</SPAN> that invoked the
    constructor.</P>

   </LI>

   <LI>

    <P><A href="http://www.whatwg.org/specs/web-workers/current-work/#run-a-worker">Run a worker</A> for the resulting <SPAN>absolute
    URL</SPAN>, with the <SPAN>script's browsing context</SPAN> of the
    script that invoked the method as the <VAR title="">owner browsing
    context</VAR>, with the <SPAN>origin</SPAN> of the <SPAN>entry
    script</SPAN> as the <VAR title="">owner origin</VAR>, and with
    <VAR title="">worker global scope</VAR> as the global scope.</P>

   </LI>

  </OL><P>This constructor must be visible when the <SPAN>script's global
  object</SPAN> is either a <CODE>Window</CODE> object or an object
  implementing the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerutils">WorkerUtils</A></CODE> interface.</P>


  <H4 id="shared-workers-and-the-sharedworker-interface"><SPAN class="secno">4.7.3 </SPAN>Shared workers and the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworker">SharedWorker</A></CODE> interface</H4>

  <PRE class="idl">[<A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-sharedworker" title="dom-SharedWorker">Constructor</A>(in DOMString scriptURL, in optional DOMString name)]
interface <DFN id="sharedworker">SharedWorker</DFN> : <A href="http://www.whatwg.org/specs/web-workers/current-work/#abstractworker">AbstractWorker</A> {
  readonly attribute <SPAN>MessagePort</SPAN> <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-sharedworker-port" title="dom-SharedWorker-port">port</A>;
};</PRE>

  <P>The <DFN id="dom-sharedworker-port" title="dom-SharedWorker-port"><CODE>port</CODE></DFN>
  attribute must return the value it was assigned by the object's
  constructor. It represents the <CODE>MessagePort</CODE> for
  communicating with the shared worker.</P>

  <P>When the <DFN id="dom-sharedworker" title="dom-SharedWorker"><CODE>SharedWorker(<VAR title="">scriptURL</VAR>, <VAR title="">name</VAR>)</CODE></DFN>
  constructor is invoked, the user agent must run the following
  steps:</P>

  <OL><LI><P><SPAN title="resolve a url">Resolve</SPAN> the <VAR title="">scriptURL</VAR> argument.</P></LI>

   <LI><P>If this fails, throw a <CODE>SYNTAX_ERR</CODE>
   exception.</P></LI>

   <LI><P>Otherwise, let <VAR title="">scriptURL</VAR> be the
   resulting <SPAN>absolute URL</SPAN>.</P></LI>

   <LI><P>Let <VAR title="">name</VAR> be the value of the second
   argument, or the empty string if the second argument was
   omitted.</P></LI>

   <LI>

    <P>If the <SPAN>origin</SPAN> of <VAR title="">scriptURL</VAR> is
    not the <SPAN title="same origin">same</SPAN> as the origin of the
    <SPAN>entry script</SPAN>, then throw a <CODE>SECURITY_ERR</CODE>
    exception.</P>

    <P class="note">Thus, scripts must be external files with the same
    scheme as the original page: you can't load a script from a <CODE title="">data:</CODE> URL or <CODE title="">javascript:</CODE>
    URL, and a <CODE>https:</CODE> page couldn't start workers using
    scripts with <CODE>http:</CODE> URLs.</P>

   </LI>

   <LI>

    <P>Let <VAR title="">docs</VAR> be the <A href="http://www.whatwg.org/specs/web-workers/current-work/#list-of-relevant-document-objects-to-add">list of relevant
    <CODE>Document</CODE> objects to add</A> given the <SPAN title="script&#39;s global object">global object</SPAN> of the <SPAN title="concept-script">script</SPAN> that invoked the
    constructor.</P>

   </LI>

   <LI>

    <P>Execute the following substeps atomically:</P>

    <OL><LI><P>Create a new <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworker">SharedWorker</A></CODE> object, which will
     shortly be associated with a <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworkerglobalscope">SharedWorkerGlobalScope</A></CODE>
     object. Let this <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworker">SharedWorker</A></CODE> object be <VAR title="">worker</VAR>.</P></LI>

     <LI><P><SPAN>Create a new <CODE>MessagePort</CODE> object</SPAN>
     owned by the <SPAN title="script&#39;s global object">global
     object</SPAN> of the script that invoked the method. Let this be
     the <VAR title="">outside port</VAR>.</P></LI>

     <LI><P>Assign <VAR title="">outside port</VAR> to the <CODE title="dom-SharedWorker-port"><A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-sharedworker-port">port</A></CODE> attribute of <VAR title="">worker</VAR>.</P></LI>

     <LI><P>Let <VAR title="">worker global scope</VAR> be
     null.</P></LI>

     <LI><P>If <VAR title="">name</VAR> is not the empty string and
     there exists a <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworkerglobalscope">SharedWorkerGlobalScope</A></CODE> object whose
     <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</A> flag
     is false, whose <CODE title="dom-WorkerGlobalScope-name">name</CODE> attribute is
     exactly equal to <VAR title="">name</VAR>, and whose <CODE title="dom-WorkerGlobalScope-location"><A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-location">location</A></CODE> attribute
     represents an <SPAN>absolute URL</SPAN> with the <SPAN>same
     origin</SPAN> as <VAR title="">scriptURL</VAR>, then let <VAR title="">worker global scope</VAR> be that
     <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworkerglobalscope">SharedWorkerGlobalScope</A></CODE> object.</P></LI>

     <LI><P>Otherwise, if <VAR title="">name</VAR> is the empty string
     and there exists a <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworkerglobalscope">SharedWorkerGlobalScope</A></CODE> object
     whose <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-closing" title="dom-WorkerGlobalScope-closing">closing</A>
     flag is false, and whose <CODE title="dom-WorkerGlobalScope-location"><A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-location">location</A></CODE> attribute
     is exactly equal to <VAR title="">scriptURL</VAR>, then let <VAR title="">worker global scope</VAR> be that
     <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworkerglobalscope">SharedWorkerGlobalScope</A></CODE> object.</P></LI>

     <LI>

      <P>If <VAR title="">worker global scope</VAR> is not null, then
      run these steps:</P>

      <OL><LI><P>If <VAR title="">worker global scope</VAR>'s <CODE title="dom-WorkerGlobalScope-location"><A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-location">location</A></CODE>
       attribute represents an <SPAN>absolute URL</SPAN> that is not
       exactly equal to <VAR title="">scriptURL</VAR>, then throw a
       <CODE>URL_MISMATCH_ERR</CODE> exception and abort all these
       steps.</P></LI>

       <LI><P>Associate <VAR title="">worker</VAR> with <VAR title="">worker global scope</VAR>.</P></LI>

       <LI><P><SPAN>Create a new <CODE>MessagePort</CODE>
       object</SPAN> owned by <VAR title="">worker global
       scope</VAR>. Let this be the <VAR title="">inside
       port</VAR>.</P></LI>

       <LI><P><SPAN>Entangle</SPAN> <VAR title="">outside port</VAR>
       and <VAR title="">inside port</VAR>.</P></LI>

       <LI><P>Return <VAR title="">worker</VAR> and perform the next
       step asynchronously.</P></LI>

       <LI><P>Create an event that uses the <CODE>MessageEvent</CODE>
       interface, with the name <CODE title="event-connect">connect</CODE>, which does not bubble, is
       not cancelable, has no default action, has a <CODE title="dom-MessageEvent-data">data</CODE> attribute whose value
       is the empty string and has a <CODE title="dom-MessageEvent-ports">ports</CODE> attribute whose
       value is an array containing only the newly created port, and
       <SPAN>queue a task</SPAN> to dispatch the event at <VAR title="">worker global scope</VAR>.</P></LI>

       <LI>

        <P><A href="http://www.whatwg.org/specs/web-workers/current-work/#add-a-document-to-the-worker's-documents" title="add a document to the worker&#39;s documents">Add to
        <VAR title="">worker global scope</VAR>'s list of <SPAN>the
        worker's <CODE>Document</CODE>s</SPAN></A> the
        <CODE>Document</CODE> objects in <VAR title="">docs</VAR>.</P>

       </LI>

       <LI>

        <P>If the <SPAN title="script&#39;s global object">global
        object</SPAN> of the <SPAN title="concept-script">script</SPAN>
        that invoked the constructor is a
        <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object, add <VAR title="">worker global scope</VAR> to the list of <A href="http://www.whatwg.org/specs/web-workers/current-work/#the-worker's-workers">the
        worker's workers</A> of the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE>
        object that is the <SPAN title="script&#39;s global object">global
        object</SPAN> of the <SPAN title="concept-script">script</SPAN>
        that invoked the constructor.</P>

       </LI>

       <LI><P>Abort all these steps.</P></LI>

      </OL></LI>

     <LI><P>Create a new <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworkerglobalscope">SharedWorkerGlobalScope</A></CODE>
     object. Let <VAR title="">worker global scope</VAR> be this new
     object.</P></LI>

     <LI><P>Associate <VAR title="">worker</VAR> with <VAR title="">worker global scope</VAR>.</P></LI>

     <LI><P>Set the <CODE title="dom-SharedWorkerGlobalScope-name"><A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-sharedworkerglobalscope-name">name</A></CODE> attribute of
     <VAR title="">worker global scope</VAR> to <VAR title="">name</VAR>.</P></LI>

     <LI><P><SPAN>Create a new <CODE>MessagePort</CODE> object</SPAN>
     owned by <VAR title="">worker global scope</VAR>. Let <VAR title="">inside port</VAR> be this new object.</P></LI>

     <LI><P><SPAN>Entangle</SPAN> <VAR title="">outside port</VAR> and
     <VAR title="">inside port</VAR>.</P></LI>

    </OL></LI>

   <LI><P>Return <VAR title="">worker</VAR> and perform the remaining
   steps asynchronously.</P></LI>

   <LI><P>Create an event that uses the <CODE>MessageEvent</CODE>
   interface, with the name <CODE title="event-connect">connect</CODE>, which does not bubble, is not
   cancelable, has no default action, has a <CODE title="dom-MessageEvent-data">data</CODE> attribute whose value is
   the empty string and has a <CODE title="dom-MessageEvent-ports">ports</CODE> attribute whose value
   is an array containing only the newly created port, and <SPAN>queue
   a task</SPAN> to dispatch the event at <VAR title="">worker global
   scope</VAR>.</P></LI>

   <LI>

    <P><A href="http://www.whatwg.org/specs/web-workers/current-work/#add-a-document-to-the-worker's-documents" title="add a document to the worker&#39;s documents">Add to
    <VAR title="">worker global scope</VAR>'s list of <SPAN>the
    worker's <CODE>Document</CODE>s</SPAN></A> the
    <CODE>Document</CODE> objects in <VAR title="">docs</VAR>.</P>

   </LI>

   <LI>

    <P>If the <SPAN title="script&#39;s global object">global object</SPAN>
    of the <SPAN title="concept-script">script</SPAN> that invoked the
    constructor is a <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object, add <VAR title="">worker global scope</VAR> to the list of <A href="http://www.whatwg.org/specs/web-workers/current-work/#the-worker's-workers">the
    worker's workers</A> of the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE>
    object that is the <SPAN title="script&#39;s global object">global
    object</SPAN> of the <SPAN title="concept-script">script</SPAN>
    that invoked the constructor.</P>

   </LI>

   <LI>

    <P><A href="http://www.whatwg.org/specs/web-workers/current-work/#run-a-worker">Run a worker</A> for <VAR title="">scriptURL</VAR>,
    with the <SPAN>script's browsing context</SPAN> of the script that
    invoked the method as the <VAR title="">owner browsing
    context</VAR>, with the <SPAN>origin</SPAN> of the <SPAN>entry
    script</SPAN> as the <VAR title="">owner origin</VAR>, and with
    <VAR title="">worker global scope</VAR> as the global scope.</P>

   </LI>

  </OL><P>This constructor must be visible when the <SPAN>script's global
  object</SPAN> is either a <CODE>Window</CODE> object or an object
  implementing the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerutils">WorkerUtils</A></CODE> interface.</P>

  <P>The <SPAN>task source</SPAN> for the tasks mentioned above is the
  <SPAN>DOM manipulation task source</SPAN>.</P>



  <H2 id="apis-available-to-workers"><SPAN class="secno">5 </SPAN>APIs available to workers</H2>

  <PRE class="idl">[Supplemental, NoInterfaceObject]
interface <DFN id="workerutils">WorkerUtils</DFN> {
  void <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-importscripts" title="dom-WorkerGlobalScope-importScripts">importScripts</A>(in DOMString... urls);
  readonly attribute <A href="http://www.whatwg.org/specs/web-workers/current-work/#workernavigator">WorkerNavigator</A> <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-worker-navigator" title="dom-worker-navigator">navigator</A>;
};
<A href="http://www.whatwg.org/specs/web-workers/current-work/#workerutils">WorkerUtils</A> implements <SPAN>WindowTimers</SPAN>;</PRE>

  <P>The DOM APIs (<CODE>Node</CODE> objects, <CODE>Document</CODE>
  objects, etc) are not available to workers in this version of this
  specification.</P>


  <H3 id="importing-scripts-and-libraries"><SPAN class="secno">5.1 </SPAN>Importing scripts and libraries</H3>

  <P>When a script invokes the <DFN id="dom-workerglobalscope-importscripts" title="dom-WorkerGlobalScope-importScripts"><CODE>importScripts(<VAR title="">urls</VAR>)</CODE></DFN> method on a
  <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object, the user agent must run the
  following steps:</P>

  <OL><LI><P>If there are no arguments, return without doing
   anything. Abort these steps.</P></LI>

   <LI><P><SPAN title="resolve a url">Resolve</SPAN> each
   argument.</P></LI>

   <LI><P>If any fail, throw a <CODE>SYNTAX_ERR</CODE>
   exception.</P></LI>

<!--
   <li><p>If any of the resulting <span title="absolute URL">absolute
   URLs</span> have an <span>origin</span> that is not the <span
   title="same origin">same</span> as the origin of the script that
   invoked the method, then throw a <code>SECURITY_ERR</code>
   exception.</p></li>
-->

   <LI>

    <P>Attempt to <SPAN>fetch</SPAN> each resource identified by the
    resulting <SPAN title="absolute URL">absolute URLs</SPAN>, from
    the <SPAN>entry script</SPAN>'s <SPAN>origin</SPAN>.</P> <!-- not
    http-origin privacy sensitive -->

   </LI>

   <LI>

    <P>For each argument in turn, in the order given, starting with
    the first one, run these substeps:</P>

    <OL><LI>

      <P>Wait for the fetching attempt for the corresponding resource
      to complete.</P>

      <P>If the fetching attempt failed, throw a
      <CODE>NETWORK_ERR</CODE> exception and abort all these
      steps.</P>

      <P>If the attempt succeeds, then convert the script resource to
      Unicode by assuming it was encoded as UTF-8, to obtain its <VAR title="">source</VAR>.</P>

      <P>Let <VAR title="">language</VAR> be JavaScript.</P>

      <P class="note">As with the worker's script, the script here is
      always assumed to be JavaScript, regardless of the MIME
      type.</P>

     </LI>

     <LI>

      <P><SPAN>Create a script</SPAN>, using <VAR title="">source</VAR> as the script source and <VAR title="">language</VAR> as the scripting language, using the
      same global object, browsing context, URL character encoding,
      base URL, and script group as the <SPAN title="concept-script">script</SPAN> that was created by the
      worker's <A href="http://www.whatwg.org/specs/web-workers/current-work/#run-a-worker">run a worker</A> algorithm.</P>

      <P>Let the newly created <SPAN title="concept-script">script</SPAN> run until it either
      returns, fails to parse, fails to catch an exception, or gets
      prematurely aborted by the "<A href="http://www.whatwg.org/specs/web-workers/current-work/#kill-a-worker">kill a worker</A>" or
      "<A href="http://www.whatwg.org/specs/web-workers/current-work/#terminate-a-worker">terminate a worker</A>" algorithms defined above.</P>

      <P>If it failed to parse, then throw an ECMAScript
      <CODE>SyntaxError</CODE> exception and abort all these
      steps. <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsECMA262">[ECMA262]</A></P>

      <P>If an exception was raised or if the script was prematurely
      aborted, then abort all these steps, letting the exception or
      aborting continue to be processed by the script that called the
      <CODE title="dom-WorkerGlobalScope-importScripts"><A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerglobalscope-importscripts">importScripts()</A></CODE>
      method.</P>

      <P>If the "<A href="http://www.whatwg.org/specs/web-workers/current-work/#kill-a-worker">kill a worker</A>" or "<A href="http://www.whatwg.org/specs/web-workers/current-work/#terminate-a-worker">terminate a
      worker</A>" algorithms abort the script then abort all these
      steps.</P>

     </LI>

    </OL></LI>

  </OL><H3 id="the-workernavigator-object"><SPAN class="secno">5.2 </SPAN>The <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workernavigator">WorkerNavigator</A></CODE> object</H3>

  <P>The <DFN id="dom-worker-navigator" title="dom-worker-navigator"><CODE>navigator</CODE></DFN> attribute
  of the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerutils">WorkerUtils</A></CODE> interface must return an instance of
  the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workernavigator">WorkerNavigator</A></CODE> interface, which represents the
  identity and state of the user agent (the client):</P>

  <PRE class="idl">interface <DFN id="workernavigator">WorkerNavigator</DFN> {};
<A href="http://www.whatwg.org/specs/web-workers/current-work/#workernavigator">WorkerNavigator</A> implements <SPAN>NavigatorID</SPAN>;
<A href="http://www.whatwg.org/specs/web-workers/current-work/#workernavigator">WorkerNavigator</A> implements <SPAN>NavigatorOnLine</SPAN>;</PRE>

  <P>Objects implementing the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workernavigator">WorkerNavigator</A></CODE> interface
  also implement the <CODE>NavigatorID</CODE> and
  <CODE>NavigatorOnLine</CODE> interfaces.
  
  <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsHTML5">[HTML5]</A>
  
  </P>

  <P>This <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workernavigator">WorkerNavigator</A></CODE> interface must not exist if the
  interface's <SPAN>relevant namespace object</SPAN> is a
  <CODE>Window</CODE> object. <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsWEBIDL">[WEBIDL]</A></P>



  <H3 id="apis-defined-in-other-specifications"><SPAN class="secno">5.3 </SPAN>APIs defined in other specifications</H3>

  <P>The <CODE title="dom-opendatabase">openDatabase()</CODE> and
  <CODE title="dom-opendatabase-sync">openDatabaseSync()</CODE>
  methods are defined in the Web SQL Database specification. <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsWEBSQL">[WEBSQL]</A></P>



  <H3 id="interface-objects-and-constructors"><SPAN class="secno">5.4 </SPAN>Interface objects and constructors</H3>

  <P>There must be no interface objects and constructors available in
  the global scope of scripts whose <SPAN>script's global
  object</SPAN> is a <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerglobalscope">WorkerGlobalScope</A></CODE> object except for
  the following:</P>

  <UL><LI><P><CODE>XMLHttpRequest</CODE> and all interface objects and
   constructors defined by the XMLHttpRequest specifications, except
   that the <SPAN>document response entity body</SPAN> must always be
   null. The <SPAN><CODE>XMLHttpRequest</CODE> base URL</SPAN> is the
   <SPAN>script's base URL</SPAN>; the
   <SPAN><CODE>XMLHttpRequest</CODE> origin</SPAN> is the script's
   <SPAN>origin</SPAN>. <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsXHR">[XHR]</A></P></LI>

   <LI><P>The interface objects and constructors defined by this
   specification.</P></LI>

   <LI><P>Constructors defined by specifications that explicitly say
   that they should be visible when the <SPAN>script's global
   object</SPAN> is a <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#dedicatedworkerglobalscope">DedicatedWorkerGlobalScope</A></CODE>, a
   <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#sharedworkerglobalscope">SharedWorkerGlobalScope</A></CODE>, or an object implementing the
   <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerutils">WorkerUtils</A></CODE> interface; the interfaces of any objects
   with such constructors; and the interfaces of any objects made
   accessible through APIs exposed by those constructors or made
   accessible through interfaces to be implemented by any objects that
   are themselves accessible to scripts whose <SPAN>script's global
   object</SPAN> implements the <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerutils">WorkerUtils</A></CODE>
   interface.</P></LI>

  </UL><P class="note">These requirements do not override the requirements
  defined by the Web IDL specification, in particular concerning the
  visibility of interfaces annotated with the <CODE title="">[NoInterfaceObject]</CODE> extended attribute.</P>


  <H3 id="worker-locations"><SPAN class="secno">5.5 </SPAN>Worker locations</H3>

  <PRE class="idl">interface <DFN id="workerlocation">WorkerLocation</DFN> {
  readonly attribute DOMString <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerlocation-href" title="dom-WorkerLocation-href">href</A>;
  readonly attribute DOMString <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerlocation-protocol" title="dom-WorkerLocation-protocol">protocol</A>;
  readonly attribute DOMString <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerlocation-host" title="dom-WorkerLocation-host">host</A>;
  readonly attribute DOMString <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerlocation-hostname" title="dom-WorkerLocation-hostname">hostname</A>;
  readonly attribute DOMString <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerlocation-port" title="dom-WorkerLocation-port">port</A>;
  readonly attribute DOMString <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerlocation-pathname" title="dom-WorkerLocation-pathname">pathname</A>;
  readonly attribute DOMString <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerlocation-search" title="dom-WorkerLocation-search">search</A>;
  readonly attribute DOMString <A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerlocation-hash" title="dom-WorkerLocation-hash">hash</A>;
};</PRE>

  <P>A <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerlocation">WorkerLocation</A></CODE> object represents an <SPAN>absolute
  URL</SPAN> set at its creation.</P>

  <P>The <DFN id="dom-workerlocation-href" title="dom-WorkerLocation-href"><CODE>href</CODE></DFN>
  attribute must return the <SPAN>absolute URL</SPAN> that the object
  represents.</P>

  <P>The <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerlocation">WorkerLocation</A></CODE> interface also has the complement
  of <SPAN>URL decomposition IDL attributes</SPAN>, <DFN id="dom-workerlocation-protocol" title="dom-WorkerLocation-protocol"><CODE>protocol</CODE></DFN>,
  <DFN id="dom-workerlocation-host" title="dom-WorkerLocation-host"><CODE>host</CODE></DFN>, <DFN id="dom-workerlocation-port" title="dom-WorkerLocation-port"><CODE>port</CODE></DFN>, <DFN id="dom-workerlocation-hostname" title="dom-WorkerLocation-hostname"><CODE>hostname</CODE></DFN>,
  <DFN id="dom-workerlocation-pathname" title="dom-WorkerLocation-pathname"><CODE>pathname</CODE></DFN>,
  <DFN id="dom-workerlocation-search" title="dom-WorkerLocation-search"><CODE>search</CODE></DFN>,
  and <DFN id="dom-workerlocation-hash" title="dom-WorkerLocation-hash"><CODE>hash</CODE></DFN>. These must
  follow the rules given for URL decomposition IDL attributes, with the
  <SPAN title="concept-uda-input">input</SPAN> being the
  <SPAN>absolute URL</SPAN> that the object represents (same as the
  <CODE title="dom-WorkerLocation-href"><A href="http://www.whatwg.org/specs/web-workers/current-work/#dom-workerlocation-href">href</A></CODE> attribute), and
  the <SPAN title="concept-uda-setter">common setter action</SPAN>
  being a no-op, since the attributes are defined to be readonly.
  
  <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsHTML5">[HTML5]</A>
  
  </P>

  <P>The <CODE><A href="http://www.whatwg.org/specs/web-workers/current-work/#workerlocation">WorkerLocation</A></CODE> interface must not exist if the
  interface's <SPAN>relevant namespace object</SPAN> is a
  <CODE>Window</CODE> object. <A href="http://www.whatwg.org/specs/web-workers/current-work/#refsWEBIDL">[WEBIDL]</A></P>




  <H2 class="no-num" id="references">References</H2><!--REFS-->

  <P>All references are normative unless marked "Non-normative".</P>

  <!-- XXX really should remove dates and version numbers from these references once and for all -->

  <DL><DT id="refsDOMCORE">[DOMCORE]</DT>
   <DD><CITE><A href="http://www.w3.org/TR/DOM-Level-3-Core/">Document
   Object Model (DOM) Level 3 Core Specification</A></CITE>, A. Le
   Hors, P. Le Hegaret, L. Wood, G. Nicol, J. Robie, M. Champion,
   S. Byrnes. W3C, April 2004.</DD>
   <!--
   <dd><cite><a href="http://simon.html5.org/specs/web-dom-core">Web
   DOM Core</a></cite>, S. Pieters. W3C, June 2009.</dd>
   -->

   <DT id="refsDOMEVENTS">[DOMEVENTS]</DT>
   <!--
   <dd><cite><a
   href="http://www.w3.org/TR/DOM-Level-3-Events/">Document Object
   Model (DOM) Level 3 Events Specification</a></cite>,
   B. H&ouml;hrmann, P. Le Hegaret, T. Pixley. W3C, December
   2007.</dd>
   -->
   <DD><CITE><A href="http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html">Document
   Object Model (DOM) Level 3 Events Specification</A></CITE>,
   D. Schepers. W3C, July 2009.</DD>

   <DT id="refsECMA262">[ECMA262]</DT>
   <DD><CITE><A href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMAScript
   Language Specification</A></CITE>. ECMA, December 2009.</DD>

   <DT id="refsHTML5">[HTML5]</DT>
   <DD><CITE><A href="http://www.whatwg.org/specs/web-apps/current-work/">HTML5</A></CITE>,
   I. Hickson. WHATWG, August 2009.</DD>

   <DT id="refsRFC2119">[RFC2119]</DT>
   <DD><CITE><A href="http://www.ietf.org/rfc/rfc2119.txt">Key words for use in
   RFCs to Indicate Requirement Levels</A></CITE>, S. Bradner. IETF, March
   1997.</DD>

   <DT id="refsWEBSQL">[WEBSQL]</DT>
   <DD><CITE><A href="http://dev.w3.org/html5/webdatabase/">Web SQL
   Database</A></CITE>, I. Hickson. W3C, July 2009.</DD>

   <DT id="refsWEBIDL">[WEBIDL]</DT>
   <!--
   <dd><cite><a href="http://www.w3.org/TR/WebIDL/">Web
   IDL</a></cite>, C. McCormack. W3C, December 2008.</dd>
   -->
   <DD><CITE><A href="http://dev.w3.org/2006/webapi/WebIDL/">Web
   IDL</A></CITE>, C. McCormack. W3C, July 2009.</DD>

   <DT id="refsXHR">[XHR]</DT>
   <!--
   <dd><cite><a href="http://www.w3.org/TR/XMLHttpRequest/">The XMLHttpRequest
   Object</a></cite>, A. van Kesteren. W3C, April
   2008.</dd>
   -->
   <DD><CITE><A href="http://dev.w3.org/2006/webapi/XMLHttpRequest-2/"><CODE>XMLHttpRequest</CODE></A></CITE>,
   A. van Kesteren. W3C, June 2009.</DD>

  </DL><H2 class="no-num" id="acknowledgements">Acknowledgements</H2> <!-- ACKS -->

  <P>Thanks to

  Aaron Boodman,
  Алексей Проскуряков (Alexey Proskuryakov),
  Anne van Kesteren,
  Ben Turner,
  Dmitry Titov,
  Drew Wilson,
  Jeremy Orlow,
  Jonas Sicking,
  Justin James,
  Kevin Hakanson,
  Maciej Stachowiak,
  Michael Nordman,
  Mike Smith,

  and

  Philip Taylor

  for their useful and substantial comments.</P>

  <P>Huge thanks to the whole Gears team, who pioneered this
  technology and whose experience has been a huge influence on this
  specification.</P>

 
</BODY></HTML>